可能我理解错误的概念,但这是我的问题:
我想在我的数据库中存储两种类型的数据:
在课堂上:
@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
表,同时保持位置的独特性。
然而,解决方案并不是最优的:我更喜欢在MOVE表中生成id
生成的@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(...)
但是当我实现这个时,我最终得到了重复的表示,因为positionAfterMove
基于指定的 ID合并,而不是自然键。< / p>
有什么方法可以让java(JPA / Hibernate / ...)基于自然键合并位置,同时还允许我使用ID作为表的键?或者,我需要手动合并头寸吗? (例如:每当我想存储移动时,我是否需要从数据库中检索positionBeforeMove
和movesLeadingToPosition
,分别将移动添加到movesLeadingFromPosition
和{{1}},然后更新数据库中的位置?)
(上下文:我正在使用Java 1.7,JPA和MySQL数据库)
答案 0 :(得分:1)
不,不可能; merge()
使用实体密钥(@Id
目标)完成。
可能需要按照JPA equivalent to Hibernate's @NaturalId中的说明添加@NaturalId
或模仿,并使用业务方法检查重复插入