2014-02-24 31 views
0

也许我理解的概念错了,但这里是我的问题:JPA:基于“自然键”企业合并

我想存储两种类型的数据在我的数据库:

  1. 游戏位置(由一些冗长的字符串唯一表示,包含两个移动列表 - 一个用于在此位置移动,另一个移动至此位置)
  2. 游戏移动(由较小的字符串表示,由两个位置连接)

在类:

@Entity 
public class Move { 
    @Id 
    @GeneratedValue 
    private long id; 
    private String representation; 
    private Position positionBeforeMove; 
    private Position positionAfterMove; 

    ... 
} 

@Entity 
public class Position { 
    @Id 
    private String representation; 
    private List<Move> movesLeadingToPosition; 
    private List<Move> movesLeadingFromPosition; 

    ... 
} 

我想存储一组的比赛。在这种情况下,这些头寸是独一无二的,并且这种举动可能会在数据库中多次出现。

我naieve实现使用两个表:

MOVE 
number id     (PK) 
varchar2 representation 
varchar2 positionBeforeMove (FK) 
varchar2 positionAfterMove  (FK) 
... 

POSITION 
varchar2 representation  (PK) 
... 

也能正常工作;使用EntityManager.merge(position)我可以增长我的POSITION表,因为我存储越来越多的游戏,同时保持位置的独特性。

但是,解决方案并不是最优的:我更喜欢生成id,就像我在MOVE表中一样!

@Entity 
public class Position { 
    @Id 
    @GeneratedValue 
    private long id; 

    private String representation; 
    private List<Move> movesLeadingToPosition; 
    private List<Move> movesLeadingFromPosition; 

    ... 
} 

MOVE 
number id     (PK) 
varchar2 representation 
number positionBeforeMove_id (FK) 
number positionAfterMove_id (FK) 
... 

POSITION 
number id;      (PK) 
varchar2 representation  (Unique) 
... 

但是,当我实现这一点,我结束了重复表示,由于基础上,EntityManager.merge(...)合并指定 ID而不是自然关键。

有什么办法让我可以让java(JPA/Hibernate/...)根据自然键合并位置,同时仍然允许我使用ID作为表的键?或者,我是否需要手动合并职位? (例如:每当我要存储的举动,将我需要从数据库中检索的positionAfterMovepositionBeforeMove,分别增加迁移到movesLeadingToPositionmovesLeadingFromPosition,然后更新数据库中的位置?)

(背景:我正在使用Java 1.7,JPA和MySQL数据库)

回答

1

不,不可能; merge()使用实体键(@Id目标)完成。

也许你需要添加一个@NaturalId或在JPA equivalent to Hibernate's @NaturalId描述和使用业务方法检查重复插入

+0

谢谢你指着我'@ NaturalId'模仿!你能否确认我将不得不手动_'合并职位'? (这似乎是在http://stackoverflow.com/questions/6058875/hibernate-natural-id-duplicate-issue中的答案)。提前致谢! – ljgw

+0

我这么认为,但是 - 如果你有时间 - 等待别人回答;也许有不同经历的人可以给我们另一种观点 –

+0

谢谢!我有时间,很高兴有怀疑证实.. – ljgw