2009-04-09 2 views
17

Получается следующее исключение, когда я пытаюсь изменить свой @ID в @Entity.Hibernate, alter identifier/primary key

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

Вместо того, чтобы использовать более ОО подход:

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

Любую идею, что разница есть?

+0

Вы пытаетесь использовать другое лицо как ПК? –

+0

Теперь я пытаюсь изменить свой секретный ключ от постоянного объекта. в sql это будет что-то вроде: «update Customers set customerId = 1492, где customer_id = 42;» и customer_id - мой личный ключ – Schildmeijer

ответ

10

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

По существу, вы создаете нового клиента и удаляете старый, и именно так я его выполнил. в спящем режиме.

[псевдокод]

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, и в любом случае, вы рискуете с параллельными процессами, которые уже имеют экземпляр «старого» клиента, что может вызвать некоторые ошибки.

+5

Прежде всего; для этой идентичности нет ограничений внешнего ключа. И, конечно, есть ситуации, когда нужно изменить первичный ключ. Я могу признать, что это не то, что вы делаете каждый день, но контекст может, без всякого сомнения, создать ситуацию, в которой он есть. – Schildmeijer

+0

Хотя я не могу представить себе такой сценарий, я признаю, что он может существовать. Я бы * хотел узнать, что это за сценарий. Кроме того, какие-либо мысли о предлагаемом решении? –

+0

Мои намерения не должны быть грубыми. мой сценарий - это что-то вроде этого. У меня есть таблица с двумя столбцами, nick :: string и number :: int, где ник является первичным ключом. И из-за ограничений встроенной памяти мы не можем позволить себе добавлять id как nickId. И людям разрешено менять ник. – Schildmeijer

3

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

21

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

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

(от EJB 3 живучесть (JPA) спецификации, пункт 2.1.4)

+0

Я не могу найти это в окончательной версии. –

3

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

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

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

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

USER_ELEC_IDELEC_DEF_IDPRIORITY

1IPAD1
1IPHONE2
1CELL3

USER_ELEC_ID и ELEC_DEF_ID являются PFKs. ПРИОРИТЕТ - это композитный FK.

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

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