2009-09-24 27 views
1

看看下面的类(单向@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参考?

回答

1

我不确定你的意思是“保持参考”?我也没有你想在这里做什么不太清楚......

你希望休眠使用新创建Team实体(例如,在这种情况下,1)的TEAM_ID插入Player实例?如果是这样,通过在@JoinColumn声明中指定可插入/可更新为false,您已明确阻止了这种情况的发生 - 您需要将它们移动到Player类中的getTeamId()方法。

你能澄清你在这里想达到什么吗?

+0

嗨Chss,添加到问题。 – 2009-09-24 22:50:27

+0

您不能“共享”整数的引用。它是不可变的,所以当TeamId值发生变化时(当Team实例保存时它会被Hibernate改变),一个全新的Integer实例被创建。因此,你最终在Team.id中获得“1”并且在PlayerId.teamId中获得旧的“-1”。正如我在回答中所述,解决此问题的方法是将insertable =“false”,updatable =“false”移动到PlayerId.getTeamId()注释。 – ChssPly76 2009-09-24 23:00:54

+0

它不应该是因为它是一个复合ID(意味着它被分配),并且teamId将通过关联来设置(和插入/更新)。但我对此并不十分确定 - 我倾向于总是使用代理键,因为它们表现出更少的头痛;对于协会来说更是如此。 – ChssPly76 2009-09-24 23:22:29

相关问题