2013-08-13 1 views
2

У меня есть отношение «многие ко многим», где таблица ссылок имеет дополнительное свойство. Следовательно, таблица ссылок также представлена ​​классом сущностей и называется Composition. Первичный ключ Composition - это @Embeddable, связанный с соответствующими объектами, например. 2 @ManyToOne ссылки.JPA @EmbeddedId: Как обновить часть составного первичного ключа?

Может случиться так, что пользователь сделает ошибку при выборе одной из двух ссылок и, следовательно, должен быть обновлен составной первичный ключ. Однако из-за того, что работает JPA (hibernate), это, конечно же, всегда будет создавать новую строку (insert) вместо обновления, а старый Composition будет по-прежнему существовать. Конечным результатом является добавление новой строки вместо обновляемой.

Вариант 1:

Старый Composition может просто быть удален до того, как новый вставлен, но это потребует обработки метод согласно это требует как старую, так и новую версию. плюс, так как обновленная версия на самом деле является новой оптимизированной блокировкой объекта, не будет работать, и, следовательно, последнее обновление всегда будет выигрывать.

Вариант 2:

Собственный запрос. Запрос также увеличивает значение столбца версии и включает версию в предложение WHERE. Throw OptimisticLockException, если количество обновлений равно 0 (одновременная модификация или удаление)

Какой лучший выбор? Каков «общий подход» к этой проблеме?

ответ

2

Почему бы не просто изменить первичный ключ Composition как UID, который автогенерируется? Затем пользователи могли бы изменить две ссылки на объединяемые объекты без необходимости удаления/повторного создания объекта Composition. Тогда будет сохранена оптимистическая блокировка.

EDIT: Например:

@Entity 
@Table(name = "COMPOSITION") 
public class Composition { 

    @Id 
    @Column(name = "ID") 
    private Long id; // Auto-generate using preferred method 

    @ManyToOne(fetch = FetchType.LAZY, optional = false) 
    @JoinColumn(.... as appropriate ....) 
    private FirstEntity firstEntity; 

    @ManyToOne(fetch = FetchType.LAZY, optional = false) 
    @JoinColumn(.... as appropriate ....) 
    private SecondEntity secondEntity; 

.... 
+0

Вы не можете иметь '@ Id' и' @ EmbeddedId' в одной и той же сущности в простом JPA. Это либо или. –

+2

@beginner_ Нет, у вас есть только '@ Id', нет' @ EmbeddedId' (см. Мое редактирование). Внешние ключи, которые ссылаются на два объекта, которые соединяются, составляют всего 2 столбца в базовой таблице. Изменение связи между сущностями - это всего лишь случай изменения этих внешних ключей, а не первичный ключ объекта/записи «Композиция», который остается в качестве исходного автоматически сгенерированного значения. – DuncanKinnear

+0

Спасибо. Так очевидно. Типичный случай быть слишком глубоким в материалах, чтобы видеть ясно больше. –