2014-02-24 2 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/...) объединить позиции, основанные на естественном ключе, но все же позволяя мне использовать идентификатор в качестве ключа к таблице? Или мне нужно было бы объединить позиции вручную? (Например: Всякий раз, когда я хочу, чтобы сохранить движение, мне нужно, чтобы получить positionAfterMove и positionBeforeMove из базы данных, добавьте движение к movesLeadingToPosition и movesLeadingFromPosition соответственно, а затем обновить свои позиции в базе данных?)

(контекст : Я использую базу данных 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

Смежные вопросы