看看下面的类(单向@OneToMany)调用保存后,Hibernate失去了引用。你知道为什么吗?
@Entity
public class Team {
private Integer id = -1;
@Id
@GeneratedValue
public Integer getId() {
return this.id;
}
private List<Player> playerList;
@OneToMany
@Cascade(CascadeType.SAVE_UPDATE)
@JoinColumn(name="TEAM_ID", insertable=false, updateable=false)
public List<Player> getPlayerList() {
return this.playerList;
}
public void addPlayer(Player player) {
player.setId(new PlayerId(getId(), getPlayerList().size()));
playerList.add(player);
}
}
通知addPlayer:团队的ID和玩家的teamId引用相同的实例,以便
AssertEquals(team.getId(), player.getPlayerId().getTeamId());
应该工作,没有?
Hibernate不会保存-1值,因为我已经声明了一个生成器策略(默认为auto)如果声明了标识符生成器,Hibernate将负责主键值赋值。我已经assined -1到团队的ID,以分享其在玩家的ID号和(打电话时addPlayer法)如下
@Embeddable
public class PlayerId implements Serializable {
private Integer teamId;
private Integer playerIndex;
// required no-arg constructor
public PlayerId() {}
public PlayerId(Integer teamId, Integer playerIndex) {
this.teamId = teamId;
this.playerIndex = playerIndex;
}
@Column(name="TEAM_ID", nullable=false)
public Integer getTeamId() {
return this.teamId;
}
@Column(name="PLAYER_INDEX", nullable=false)
public Integer getPlayerIndex() {
return this.playerIndex;
}
// getters and setters
public boolean equals(Object o) {
if(o == null)
return false;
if(!(o instanceof PlayerId))
return false;
PlayerId other = (PlayerId) o;
if(!(getTeamId().equals(other.getTeamId()))
return false;
if(!(getPlayerIndex().equals(other.getPlayerIndex()))
return false;
return true;
}
}
但是,当我打电话(在addPlayer以一个特殊的外观)
Team team = new Team();
Player player = new Player();
// teamId property in PlayerId references Team id
team.addPlayer(player);
session.save(team);
,我看到的数据库我得到
PLAYER
TEAM_ID PLAYER_INDEX
-1 0
TEAM
ID
1
当我节省
后的比较3210个日志输出
INSERT INTO TEAM VALUES()
// SELECT BEFORE SAVING OR UPDATING WHEN USING A COMPOUND PRIMARY KEY
SELECT * FROM PLAYER WHERE TEAM_ID = ? AND PLAYER_INDEX = ?
INSERT INTO PLAYER (TEAM_ID, PLAYER_INDEX) VALUES (?, ?)
所以你知道为什么Hibernate的保存队和它的球员后,失去了玩家的teamId物业团队的ID参考?
嗨Chss,添加到问题。 – 2009-09-24 22:50:27
您不能“共享”整数的引用。它是不可变的,所以当TeamId值发生变化时(当Team实例保存时它会被Hibernate改变),一个全新的Integer实例被创建。因此,你最终在Team.id中获得“1”并且在PlayerId.teamId中获得旧的“-1”。正如我在回答中所述,解决此问题的方法是将insertable =“false”,updatable =“false”移动到PlayerId.getTeamId()注释。 – ChssPly76 2009-09-24 23:00:54
它不应该是因为它是一个复合ID(意味着它被分配),并且teamId将通过关联来设置(和插入/更新)。但我对此并不十分确定 - 我倾向于总是使用代理键,因为它们表现出更少的头痛;对于协会来说更是如此。 – ChssPly76 2009-09-24 23:22:29