在JPA中使用继承时的复合外键问题



我有一个JPA实体StatsEntity,它有一个复合主键,也作为另一个实体花表的外键。这是使用@JoinColumns({@JoinColumn…})注释设置的@OneToOne关系。

StatsEntity扩展了另一个实体CoreStatsEntity,该实体设置为@MappedSuperClass,其中RosterEntity使用SINGLE_TABLE继承策略扩展了另一个实体CoreStatsEntity。

@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。关键

 @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

 @Entity
 @DiscriminatorValue("20")
  public class RosterEntity extends
    CoreRosterEntity  {
    //.... attributes, getters, setters
    }

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

}

coeroster .java中的coeroster . 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);
    }
}

当我持久化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映射是否正确?如果它是正确的,那么为什么当我尝试使用primarykey查找实体时出现此错误。

您还没有发布完整的源代码,特别是主键类的源代码,但是您已经将外键映射为只读,这是在多次映射单个列时需要的。

我看到,然而,你id列是完全相同的3列,是外键到RosterEntity,对吗?在这种情况下,这个RosterEntity应该是您的ID,这将简化您的设计。

getId()方法的返回类型是什么?问题可能与IdClass的定义或使用有关。

最新更新