【发布时间】:2020-10-26 11:15:29
【问题描述】:
我有一个游戏实体,通过Map + @MapKeyColumn 引用两个分数,其中一个实体用于主队,一个用于客队:
我决定为此使用Boolean 列is_home。我映射了@MapKeyColumn 关系没有 insertable = false, updatable = false,使该注释可写关于is_home 列。
由于每列可能只有一个可写字段/注释,我不得不将insertable = false, updatable = false 添加到Score 实体字段home 上的@Id 映射,见下文。
游戏:
@Entity
@Table(name = "Games")
public class Game implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@Column
private Integer id;
@Basic(optional = false)
@Column(name = "scheduled_tipoff")
private LocalDateTime scheduledTipoff;
@OneToMany(mappedBy = "game")
@MapKeyColumn(name = "is_home") <- writable
private Map<Boolean, Score> scores;
...
}
得分:
@Entity
@Table(name = "Scores")
@IdClass(ScoreId.class)
public class Score implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@Column(name = "is_home", insertable = false, updatable = false) <- not writable
private Boolean home;
@Basic
@Column(name = "final_score")
private Integer finalScore;
@Id
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "game_id")
private Game game;
...
}
ScoreId:
public class ScoreId implements Serializable
{
private static final long serialVersionUID = 1L;
private Integer game;
private Boolean home;
...
}
这会导致使用 EclipseLink 的异常:
例外
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-28013] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Unable to deploy PersistenceUnit [BBStatsPU] in invalid state [DeployFailed].
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28019] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Deployment of PersistenceUnit [BBStatsPU] failed. Close all factories for this PersistenceUnit.
Internal Exception: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions:
---------------------------------------------------------
Exception [EclipseLink-46] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: There should be one non-read-only mapping defined for the primary key field [Scores.is_home].
Descriptor: RelationalDescriptor(net.bbstats.entity.Score --> [DatabaseTable(Scores)])
Runtime Exceptions:
---------------------------------------------------------
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:634)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getAbstractSession(EntityManagerFactoryDelegate.java:222)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:330)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:350)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:313)
at org.jboss.as.jpa.container.TransactionScopedEntityManager.createEntityManager(TransactionScopedEntityManager.java:187)
at org.jboss.as.jpa.container.TransactionScopedEntityManager.getOrCreateTransactionScopedEntityManager(TransactionScopedEntityManager.java:157)
at org.jboss.as.jpa.container.TransactionScopedEntityManager.getEntityManager(TransactionScopedEntityManager.java:87)
at org.jboss.as.jpa.container.AbstractEntityManager.createNamedQuery(AbstractEntityManager.java:101)
at net.bbstats.framework.service.Repository.findByNamedQuery(Repository.java:173)
at net.bbstats.framework.service.BaseEntityService.findByNamedQuery(BaseEntityService.java:467)
at net.bbstats.framework.service.BaseEntityService.findByNamedQuery(BaseEntityService.java:453)
at net.bbstats.framework.service.BaseEntityService.findByNamedQuery(BaseEntityService.java:429)
at net.bbstats.framework.service.BaseEntityService.findAllWithFetchGraph(BaseEntityService.java:385)
... 194 more
Caused by: Exception [EclipseLink-28013] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Unable to deploy PersistenceUnit [BBStatsPU] in invalid state [DeployFailed].
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28019] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Deployment of PersistenceUnit [BBStatsPU] failed. Close all factories for this PersistenceUnit.
Internal Exception: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions:
---------------------------------------------------------
Exception [EclipseLink-46] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: There should be one non-read-only mapping defined for the primary key field [Scores.is_home].
Descriptor: RelationalDescriptor(net.bbstats.entity.Score --> [DatabaseTable(Scores)])
Runtime Exceptions:
---------------------------------------------------------
at org.eclipse.persistence.exceptions.EntityManagerSetupException.cannotDeployWithoutPredeploy(EntityManagerSetupException.java:193)
... 208 more
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-28019] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Deployment of PersistenceUnit [BBStatsPU] failed. Close all factories for this PersistenceUnit.
Internal Exception: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions:
---------------------------------------------------------
Exception [EclipseLink-46] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: There should be one non-read-only mapping defined for the primary key field [Scores.is_home].
Descriptor: RelationalDescriptor(net.bbstats.entity.Score --> [DatabaseTable(Scores)])
问题
我知道 JPA 实现可能假设每个 @Id 字段都自动可写,但我想知道:JPA 是否在任何地方指定了这一点?
我目前不明白为什么要做出这种可写性假设。
如果没有指定,那么这是一个错误吗?
【问题讨论】:
-
您永远无法更改实体中的 ID 值,因此几乎暗示了可更新 = 假,只是 eclipseLink 在其映射中将可插入与可更新绑定以匹配先前存在的只读概念它适用于 JPA。 JPA 要求,如果要插入一个实体,它必须有一个它可以在实体内控制的 ID 值 - 在这种情况下,您试图让 ID 由其他一些外部映射(game.scores 关系) 这不符合成为实体的含义。这使它更像是一个嵌入式对象。
-
您介意将其发布为答案吗?它很可能不会变得更好......
标签: hibernate jpa eclipselink