2014-02-24 61 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