Подтвердить что ты не робот

Hibernate, идентификатор изменения/первичный ключ

Я получаю следующее исключение, когда пытаюсь изменить свой @ID в @Entity.

identifier of an instance of com.google.search.pagerank.ItemEntity was altered from 1 to 2.

Я знаю, что я изменяю первичный ключ в своей таблице. Я использую аннотации JPA.

Я решил это, используя этот единственный запрос HQL: update Table set name=:newName where name=:oldName

Вместо использования более OO-подхода:

beginTransaction();
T e = session.load(...);
e.setName(newName);
session.saveOrUdate(e);
commit();

Любая идея в том, что такое diff?

4b9b3361

Ответ 1

Я не могу представить, почему вы хотите это сделать. Вообще. Почему вы изменили бы идентификатор сущности? Вам также необходимо обновить все внешние ключи в других таблицах, которые указывают на него. Кажется, боль, без усиления. Вероятно, вам лучше сделать это "бизнес-ключ" (простое свойство) и использовать более постоянный ключ суррогата. У меня такое чувство, что вы все это делаете неправильно, но если вы настаиваете...

По сути дела, вы создаете нового Клиента и удаляете старый, и как я это делаю в Hibernate.

[псевдокод]

Begin Transaction

// create new customer from old
newC = Session.Load<Customer>(42)
Session.Evict(newC)
newC.Id = 1492
Session.Save(newC)

// update other relationships to point to newC
// ....

// delete old customer
oldC = Session.Load<Customer>(42)
Session.Delete(oldC)

Commit Transaction

Тем не менее, вам, вероятно, лучше всего делать это за один раз в простой транзакции SQL, и в любом случае вы рискуете иметь параллельные процессы, у которых уже есть экземпляр "старого" клиента, что может вызвать некоторые ошибки.

Ответ 2

Собственно, согласно спецификации JPA, запрещено изменять первичный ключ:

Приложение не должно изменять значение первичного ключа [8]. Поведение undefined, если это происходит. [9]

(из спецификации сохранения EJB 3 (JPA), пункт 2.1.4)

Ответ 3

Мой друг, Ты прав. Нет способа (или я не знаю способа) изменить первичный ключ без использования инструкций HQL. Это не нормально, но это правда.

Ответ 4

Это не решение, так как я считаю, что был дан ответ выше.

Однако я хотел предложить то, что, по моему мнению, было правильным сценарием для этого. (Комментарии приветствуются)

1) Таблица USER_ELECTRONICS имеет много-ко-многим с таблицей ELECTRONICS_DEF

2) Это много-ко многим - упорядоченный список. Каждый USER_ELECTRONIC_ID имеет приоритетный список ELECTRONICS_DEF_ID. Например, у меня есть IPhone, IPad, сотовый телефон, и я оцениваю их по порядку, насколько они мне нравятся. Для этого у меня есть таблица USER_ELEC_PRIORITY_MAP, которая выглядит так:

USER_ELEC_ID ELEC_DEF_ID PRIORITY

1 IPAD 1
1 IPHONE 2
1 CELL 3

USER_ELEC_ID, а ELEC_DEF_ID - PFK. ПРИОРИТЕТ - это композитный FK.

3) Когда я хочу переупорядочить таблицу в соответствии с моими предпочтениями (мой новый IPad2 находится сверху в списке, а iPad переходит на # 4), мне нужно обновить часть Composite FK (ПРИОРИТЕТ).