我有以下简单的设计:
球员统计数据是每个球员的统计数据,它为球员保存整场比赛的状态,例如球衣号码。
它引用了一个团队成员,该成员由特定名单中的球员识别(基本上,一个球员可以是多个名单的一部分,例如在一个赛季中为多个球队效力的球员)。
球员统计数据与比赛的得分相关,无论是主场还是客场得分。它基本上是一个带有附加属性/列的连接表。你明白了。
因此,表所引用的两个PlayerStats
表都有一个复合 PK。我使用派生标识符映射PlayerStat
实体,见下文。
评分实体+ID类(无特殊):
@Entity
@Table(name = "Scores")
@IdClass(ScoreId.class)
public class Score implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@Column(name = "game_id")
private Integer gameId;
@Id
@Column(name = "is_home")
private Boolean home;
@Basic
@Column(name = "final_score")
private Integer finalScore;
@OneToMany(mappedBy = "score")
private List<PlayerStat> playerStats;
...
}
public class ScoreId implements Serializable
{
private static final long serialVersionUID = 1L;
private Integer gameId;
private Boolean home;
...
}
团队成员实体+ID类(无特殊):
@Entity
@Table(name = "TeamMembers")
@IdClass(TeamMemberId.class)
public class TeamMember implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@Column(name = "player_id")
private Integer playerId;
@Id
@Column(name = "roster_id")
private Integer rosterId;
@OneToMany(mappedBy = "teamMember")
private List<PlayerStat> playerStats;
...
}
public class TeamMemberId implements Serializable
{
private static final long serialVersionUID = 1L;
private Integer playerId;
private Integer rosterId;
...
}
玩家统计实体 + ID 类(派生标识符):
@Entity
@Table(name = "PlayerStats")
@IdClass(PlayerStatId.class)
public class PlayerStat implements Serializable
{
private static final long serialVersionUID = 1L;
@Basic(optional = false)
@Column(name = "jersey_nbr")
private Integer jerseyNbr;
@Id
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "game_id", referencedColumnName = "game_id")
@JoinColumn(name = "is_home", referencedColumnName = "is_home")
private Score score;
@Id
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "player_id", referencedColumnName = "player_id")
@JoinColumn(name = "roster_id", referencedColumnName = "roster_id")
private TeamMember teamMember;
...
}
public class PlayerStatId implements Serializable
{
private static final long serialVersionUID = 1L;
private ScoreId score;
private TeamMemberId teamMember;
public PlayerStatId()
{
}
public ScoreId getScoreId()
{
return score;
}
public void setScoreId(ScoreId scoreId)
{
this.score = scoreId;
}
public TeamMemberId getTeamMemberId()
{
return teamMember;
}
public void setTeamMemberId(TeamMemberId teamMemberId)
{
this.teamMember = teamMemberId;
}
...
}
例外:
11:44:27,315 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 78) MSC000001: Failed to start service jboss.persistenceunit."bbstatstest-1.0.war#BBStatsPU": org.jboss.msc.service.StartException in service jboss.persistenceunit."bbstatstest-1.0.war#BBStatsPU": javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [BBStatsPU] failed.
Internal Exception: Exception [EclipseLink-7150] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Invalid composite primary key specification. The names of the primary key fields or properties in the primary key class [net.bbstats.entity.PlayerStatId] and those of the entity bean class [class net.bbstats.entity.PlayerStat] must correspond and their types must be the same. Also, ensure that you have specified ID elements for the corresponding attributes in XML and/or an @Id on the corresponding fields or properties of the entity class.
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:198)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:128)
at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:658)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:212)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1348)
at java.lang.Thread.run(Thread.java:748)
at org.jboss.threads.JBossThread.run(JBossThread.java:485)
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [BBStatsPU] failed.
Internal Exception: Exception [EclipseLink-7150] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Invalid composite primary key specification. The names of the primary key fields or properties in the primary key class [net.bbstats.entity.PlayerStatId] and those of the entity bean class [class net.bbstats.entity.PlayerStat] must correspond and their types must be the same. Also, ensure that you have specified ID elements for the corresponding attributes in XML and/or an @Id on the corresponding fields or properties of the entity class.
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.createPredeployFailedPersistenceException(EntityManagerSetupImpl.java:2109)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:2085)
at org.eclipse.persistence.jpa.PersistenceProvider.createContainerEntityManagerFactoryImpl(PersistenceProvider.java:350)
at org.eclipse.persistence.jpa.PersistenceProvider.createContainerEntityManagerFactory(PersistenceProvider.java:316)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.createContainerEntityManagerFactory(PersistenceUnitServiceImpl.java:365)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.access$1300(PersistenceUnitServiceImpl.java:71)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:190)
... 9 more
Caused by: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [BBStatsPU] failed.
Internal Exception: Exception [EclipseLink-7150] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Invalid composite primary key specification. The names of the primary key fields or properties in the primary key class [net.bbstats.entity.PlayerStatId] and those of the entity bean class [class net.bbstats.entity.PlayerStat] must correspond and their types must be the same. Also, ensure that you have specified ID elements for the corresponding attributes in XML and/or an @Id on the corresponding fields or properties of the entity class.
at org.eclipse.persistence.exceptions.EntityManagerSetupException.predeployFailed(EntityManagerSetupException.java:233)
... 16 more
Caused by: Exception [EclipseLink-7150] (Eclipse Persistence Services - 2.7.7.v20200504-69f2c2b80d): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Invalid composite primary key specification. The names of the primary key fields or properties in the primary key class [net.bbstats.entity.PlayerStatId] and those of the entity bean class [class net.bbstats.entity.PlayerStat] must correspond and their types must be the same. Also, ensure that you have specified ID elements for the corresponding attributes in XML and/or an @Id on the corresponding fields or properties of the entity class.
at org.eclipse.persistence.exceptions.ValidationException.invalidCompositePKSpecification(ValidationException.java:1198)
at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.validatePrimaryKey(EntityAccessor.java:1531)
at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.processMappingAccessors(EntityAccessor.java:1251)
at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.process(EntityAccessor.java:701)
at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processStage2(MetadataProject.java:1879)
at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.processORMMetadata(MetadataProcessor.java:580)
at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processORMetadata(PersistenceUnitProcessor.java:629)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:2006)
... 14 more
问题:
映射有什么问题?
该PlayerStat
实体有两个关系score
,teamMember
并且各自@IdClass
被调用PlayerStatId
有两个嵌套的复合 PK类引用,根据需要调用score
和teamMember
,它们的类型是各自的 PK 类ScoreId
和TeamMemberId
。
我在 WildFly 20 环境中使用最新的 EclipseLink 2.7.7。
这可能是某种错误吗?
我查看了几个描述派生标识符的来源,但我没有看到映射存在任何固有的错误。