Возможно, я понять понятие неправильно, но вот моя проблема:JPA: слияние субъектов, основанные на «естественном ключе»
Я хочу, чтобы хранить два типа данных в моей базе данных:
- позиции игры (однозначно представлены некоторой длинной строкой, содержащей два списка ходов - один для перемещений, возможных в этом положении, и один для перемещений, ведущих к этой позиции)
- игровые движения (представлены меньшей строкой, связывающей две позиции)
В классах:
@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/...) объединить позиции, основанные на естественном ключе, но все же позволяя мне использовать идентификатор в качестве ключа к таблице? Или мне нужно было бы объединить позиции вручную? (Например: Всякий раз, когда я хочу, чтобы сохранить движение, мне нужно, чтобы получить positionAfterMove
и positionBeforeMove
из базы данных, добавьте движение к movesLeadingToPosition
и movesLeadingFromPosition
соответственно, а затем обновить свои позиции в базе данных?)
(контекст : Я использую базу данных Java 1.7, JPA и MySQL)
Спасибо за указание мне '@ NaturalId'! Можете ли вы подтвердить, что мне придется «ругать позиции вручную»? (это, кажется, ответ в http://stackoverflow.com/questions/6058875/hibernate-natural-id-duplicate-issue). Заранее спасибо! – ljgw
Я так думаю, но - если у вас есть время - подождите, пока кто-нибудь ответит; возможно, люди с различным опытом могут дать нам еще одну точку зрения –
спасибо! У меня есть время, и приятно иметь подозрения. – ljgw