2010-08-25 2 views
0

Я alwways получаю следующее сообщение об ошибке:JPA: Слияние @OneToMany Дубликат ошибка ввода

Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '2-1' for key 'PRIMARY' 
Error Code: 1062 
Call: INSERT INTO ENTITY_ENTITY (relationships_ID, Entity_ID) VALUES (?, ?) 
    bind => [1, 2] 
Query: DataModifyQuery(sql="INSERT INTO ENTITY_ENTITY (relationships_ID, Entity_ID) VALUES (?, ?)") 

Мои классы выглядят как:

@javax.persistence.Entity 
public class Entity { 


    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE) 
    protected Long id; 

    @Column(nullable=false, updatable=false) 
    protected String name; 

    @OneToMany(cascade=CascadeType.MERGE) 
    protected Collection<Entity> relationships = new ArrayList<Entity>(); 
} 

Один экземпляр этого класса может ссылаться на другие экземпляры тот же тип (саморегуляция). Теперь, создавая один экземпляр, который ссылается на другой, все работает нормально. Но проблема в том, когда такой (отсоединенный - я не совсем уверен, потому что экземпляр редактируется через форму Facelets) экземпляр обновляется, то есть имя, а затем, выполняя операцию слияния EntityManager, исключение - как упоминалось выше - бросается.

РЕДАКТИРОВАТЬ:
1. Создать один экземпляр Entity (т.е. Е1).
2. Персистировать E1 через em.persist (E1).
3. Позже создайте еще один экземпляр объекта (E2), который refreneces E1 через свойство отношения.
4. И сохраняйте E2: em.persist (E2).

--- До сих пор все работает нормально.

  1. Загрузить, чтобы просмотреть все сохраненные экземпляры Entity и выбрать E2 для редактирования (через веб-интерфейс Facelet).
  2. Изменение, то есть имя E2.
  3. Для сохранения изменений: Позвоните em.merge (E2).

--- Теперь Исключение брошено!

END EDIT

Что случилось с моим кодом? Пожалуйста, помогите мне !!!

+0

Можете ли вы показать некоторые (псевдо) код для всего потока и зафиксировать отображение (или название)? –

ответ

3

Кажется, что вы отделяете или объединяете свои объекты, как-то искажая объект, чтобы иметь две ссылки на одну и ту же сущность, или думать, что ссылка является новой, когда она была существующей. Это вызывает INSERT в таблицу соединения OneToMany, которая является дубликатом и вызывает нарушение ограничения.

Попытка отладки или проверки состояния коллекции на каждом этапе, получает ли она дублированный экземпляр, добавленный к нему?

Возможно, это может иметь какое-то отношение к кешированию или отслеживанию изменений. Вы можете попытаться отключить общий кэш или обновить объект или отключить переплетение.

http://wiki.eclipse.org/EclipseLink/FAQ/How_to_disable_the_shared_cache%3F

http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching#How_to_refresh_the_cache

http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#How_to_Disable_Weaving_Using_EclipseLink_Persistence_Unit_Properties

+0

Хорошо, теперь я нашел проблему. Отладка была немного сложной, но ваша догадка была правильной! Я не уверен, почему EclipseLink получил во время слияния 2 ссылки, но это так. Удаляя все структуры содержимого и таблицы, а также постепенно воссоздавая класс «Entity», проблема была решена. СПАСИБО! – gerry

+0

Это была моя проблема. upvoted & Thx! –

+0

Я также видел поведение, описанное выше. Ни один из советов не работал для меня, поэтому я был вынужден переключиться на Hibernate. Теперь все работает! – Adam