2013-10-25 51 views
1

我很努力根据实体映射与复合主键的一对多双向关系。我创建了一些代表我想要做的事情的类。他们只是为了更容易解释,但我认为他们表达了我想要做的很好。与复合实体关键的双向OneToMany关系导致空标识符

我没有实现一些接口/方法,但是我可以确保它在我不将一组比赛添加到玩家/游戏实体时起作用。所以我的映射有些问题。

当我试图找到一个实体(几乎可以做任何事情)时,Hibernate 4.x会产生一个空标识符错误,并且没有更多关于错误的信息。

当我在“one”上有一个复合主键并且我想要双向导航时,映射此映射的正确方法是什么?

@Entity 
@IdClass(TournamentPk.class) 
public class Tournament { 

    @Id 
    @ManyToOne 
    @JoinColumn("player_id") 
    private Player player; 
    @Id 
    @ManyToOne 
    @JoinColumn("game_id") 
    private Game game; 
    private int score; 

    // Getters and Setters 
    // Hashcode and Equals 
} 

// Primary key class. 
public class TournamentPk { 

    private Player player; 
    private Game game; 

    // Getters and Setters 
    // Hashcode and Equals 
} 


@Entity 
public class Player { 

    // ID 
    // Other fields 

    @OneToMany(fetchType = FetchType.EAGER, mappedBy = "player") 
    private Set<Tournament> tournaments; 

    // Getters and Setters 
    // Hashcode and Equals 
} 

@Entity 
public class Game { 

    // ID 
    // Other fields 

    @OneToMany(fetchType = FetchType.EAGER, mappedBy = "game") 
    private Set<Tournament> tournaments; 

    // Getters and Setters 
    // Hashcode and Equals 
} 
+0

尝试使用'@ EmbeddedId',而不是'@ IdClass' – Simon

+0

你能提供确切的异常信息?当你尝试找到什么类型的实体时会发生错误? –

回答

2

你的问题是,你有没有允许的类型@Id领域的注解(Player类型和Game的e.g)。有关详细信息,请参阅@Id注释的文档

完整性注意事项:some references允许另一个实体类使用@Id注释。

  1. 在你的地方,我会在你的Tournament实体的独立@Id private Long id;场+在游戏+播放器结合的标准映射的@Unique约束。
  2. 如果你真的想坚持@IdClass,你可以尝试在你的锦标赛类中添加两个允许的字段(我找到了类似的映射here(搜索@IdClass))。

@Entity 
    @IdClass(TournamentPk.class) 
    public class Tournament { 

    @Id 
    @Column(name="player_id", insertable = false, updatable = false) 
    private Long playerId; 

    @ManyToOne 
    @JoinColumn("player_id")//consider adding cascade=PERSIST 
    private Player player; 

    @Id 
    @Column(name="game_id", insertable = false, updatable = false) 
    private Long gameId; 

    @ManyToOne 
    @JoinColumn("game_id")//consider adding cascade=PERSIST 
    private Game game; 
    private int score; 

    // Getters and Setters 
    // Hashcode and Equals 
} 

    public class TournamentPk { 

    private Long playerId; 
    private Long gameId; 

    // Getters and Setters 
    // Hashcode and Equals 
} 
+0

是的,我意识到使用实体作为PK没有工作,所以我改变了嵌入ID,并使用了你写的相同的映射。但是当我做了我有重复列映射(列和连接列有相同的名称),所以我不得不添加insertable = false和updateable = false。但是,当我保存时,我没有在数据库中获得记录.. – LuckyLuke

+0

你的意思是你尝试了解决方案2('@ IdClass'而不是'@ EmbeddedId')。我已将'updatable = false,insertable = false'添加到我的代码中,谢谢。你确定当你试图保存一个记录时你没有发生异常(很难相信)?如果你得到一个,请发布堆栈跟踪。您如何看待解决方案1?你是否尝试/想用'@ EmbeddedId'而不是'@ IdClass'? –

+0

我已经改变了方法1,我想我更近一步通过在可嵌入的ID和另一组manytoone中使用简单的字段。我认为这是正确的。我明天一定要看。我会发布我找到的。 – LuckyLuke

相关问题