私はJPA Entity StatsEntityを持っています。これには複合主キーがあり、これは別のエンティティ・ロスターの外部キーです。これは@OneToOneの関係として設定されています。@JoinColumns({@ JoinColumn ...})注釈。JPAで継承を使用しているときのコンポジット外部キーの問題
StatsEntityは、別のエンティティCoreStatsEntityを@MappedSuperClassとしてセットアップします。ここで、RosterEntityはSINGLE_TABLE継承戦略を使用して別のエンティティCoreRosterを拡張します。
@Entity
@Table(name = "Stats")
@IdClass(value = StatsEntity.Key.class)
public class StatsEntity extends CoreStatsEntity implements
Stats {
@Id
private Integer competitionId;
@Id
private Integer playerId;
@Id
private Integer teamId;
@OneToOne
@JoinColumns({
@JoinColumn(name = "competitionId", referencedColumnName = "competitionId", insertable = false, updatable=false),
@JoinColumn(name = "playerId", referencedColumnName = "personId", insertable = false, updatable=false),
@JoinColumn(name = "teamId", referencedColumnName = "teamId", insertable = false, updatable=false) })
private RosterEntity roster;
....
}
StatsEntity.Key
@Embeddable
public static class Key implements Serializable {
private static final long serialVersionUID = -7349082038890396790L;
@Column(name = "competitionId", insertable = false, updatable = false)
private Integer competitionId;
@Column(name = "playerId", insertable = false, updatable = false)
private Integer playerId;
@Column(name = "teamId", insertable = false, updatable = false)
private Integer teamId;
public Key() {
super();
}
public Key(int competitionId, int playerId, int teamId) {
this.competitionId = Integer.valueOf(competitionId);
this.playerId = Integer.valueOf(playerId);
this.teamId = Integer.valueOf(teamId);
}
public int getTeamId() {
return teamId.intValue();
}
public void setTeamId(int teamId) {
this.teamId = Integer.valueOf(teamId);
}
public int getPlayerId() {
return playerId.intValue();
}
public void setPlayerId(int playerId) {
this.playerId = Integer.valueOf(playerId);
}
public int getCompetitionId() {
return competitionId.intValue();
}
public void setCompetitionId(int CompetitionId) {
this.competitionId = Integer.valueOf(CompetitionId);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object object) {
if (object == this) {
return true;
}
if (!(object instanceof Key)) {
return false;
}
Key other = (Key) object;
return Utils.equals(other.getTeamId(), this.getTeamId())
&& Utils.equals(other.getPlayerId(), this.getPlayerId())
&& Utils.equals(other.getCompetitionId(),
this.getCompetitionId());
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return Utils.hashCode(this.teamId, this.playerId,
this.competitionId);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return Utils.toString("CompetitionPlayerStatsEntity.Key",
this.teamId, this.playerId, this.competitionId);
}
}
CoreStatsEntity.java
@MappedSuperclass
public abstract class CoreStatsEntity
{}
RosterEntity
CoreRoster.java内部CoreRosterEntity.java
@Entity
@DiscriminatorValue("0")
@Table(name="Roster")
@IdClass(CoreRoster.Key.class)
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="discriminator", discriminatorType=DiscriminatorType.INTEGER)
public class CoreRosterEntity {
private static final long serialVersionUID = 1521639115446682871L;
@Id
private Integer competitionId;
@Id
private Integer teamId;
@Id
private Integer playerId;
//.. getters, setters and other attributes
}
CoreRoster.Key.class
@Embeddable
public static class Key implements Serializable {
private static final long serialVersionUID = 2L;
@Column(name="competitionId", nullable=false)
private Integer competitionId;
@Column(name="teamId", nullable=false)
private Integer teamId;
@Column(name="personId", nullable=false)
private Integer playerId;
public Key() {
super();
}
public Key(int competitionId, int teamId, int playerId) {
this.competitionId = Integer.valueOf(competitionId);
this.teamId = Integer.valueOf(teamId);
this.playerId = Integer.valueOf(playerId);
}
public int getPlayerId() {
return playerId.intValue();
}
public void setPlayerId(int playerId) {
this.playerId = Integer.valueOf(playerId);
}
public int getTeamId() {
return teamId.intValue();
}
public void setTeamId(int teamId) {
this.teamId = Integer.valueOf(teamId);
}
public int getCompetitionId() {
return this.competitionId.intValue();
}
public void setCompetitionId(int competitionId) {
this.competitionId = Integer.valueOf(competitionId);
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object object) {
if (object == this) { return true; }
if (!(object instanceof Key)) { return false; }
Key other = (Key) object;
return Utils.equals(other.getCompetitionId(), this.getCompetitionId()) &&
Utils.equals(other.getTeamId(), this.getTeamId()) &&
Utils.equals(other.getPlayerId(), this.getPlayerId());
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return Utils.hashCode(this.competitionId, this.teamId,
this.playerId);
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return Utils.toString("CoreRoster.Key",
this.competitionId, this.teamId,
this.playerId);
}
}
IはStatsEntityを保持する場合、それが持続します。私はそれはそれは私にエラーを与える主キー使用して見つけるしようとすると、しかし:
StatsEntity playerStats = new StatsEntity();
//set all values
this.persist(playerStats);
entityManager.find(StatsEntity.class, playerStats.getId()); //getId returns the composite primary key
java.lang.IllegalArgumentException: Provided id of the wrong type for class com.sports.RosterEntity. Expected: class com.sports.CoreRoster$Key, got class com.espn.sports.StatsEntity$Key
をここに私の最初の質問は、私が正しい与えたりしていない@OneToOneマッピングのですか? 正しければ、プライマリキーを使用してエンティティを検索しようとすると、なぜこのエラーが表示されるのですか?
は編集しました。 getIdの戻り値の型はObjectですが、StatsEntity.Keyのオブジェクトを返します。 –
Roster.KeyはそのIDの列を別の名前にすることはできません(playerIdの代わりにpersonId) –
(DBAのおかげで)DB列にマイナーチェンジを追加しました。 RosterEntityとして。働いた。ありがとう –