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

Найдено общие ссылки на коллекцию org.hibernate.HibernateException

Я получил это сообщение об ошибке:

error: найдены общие ссылки на коллекцию: Person.relatedPersons

Когда я попытался выполнить addToRelatedPersons(anotherPerson):

person.addToRelatedPersons(anotherPerson);
anotherPerson.addToRelatedPersons(person);

anotherPerson.save();
person.save();

Мой домен:

Person {

 static hasMany = [relatedPersons:Person];

}

любая идея, почему это происходит?

4b9b3361

Ответ 1

Hibernate показывает эту ошибку, когда вы пытаетесь сохранить более одного экземпляра сущности, совместно использующего ссылку same для коллекции (т.е. идентификатор коллекции в отличие от равенства коллекции).

Обратите внимание, что это означает, что те же коллекция, а не элемент коллекции - другими словами relatedPersons на person и anotherPerson должны быть одинаковыми. Возможно, вы сбросите эту коллекцию после загрузки объектов? Или вы инициализировали обе ссылки с одним экземпляром коллекции?

Ответ 2

У меня была та же проблема. В моем случае проблема заключалась в том, что кто-то использовал BeanUtils для копирования свойств одного объекта в другой, поэтому мы получили два объекта, ссылающихся на одну и ту же коллекцию.

Учитывая, что я потратил некоторое время на изучение этой проблемы, я бы рекомендовал следующий контрольный список:

  • Поиск сценариев, таких как entity1.setCollection(entity2.getCollection()) и getCollection, возвращает внутреннюю ссылку на коллекцию (если getCollection() возвращает новый экземпляр коллекции, тогда вам не нужно беспокоиться).

  • Посмотрите, правильно ли реализована функция clone().

  • Найдите BeanUtils.copyProperties(entity1, entity2).

Ответ 3

Объяснение практики. Если вы попытаетесь сохранить свой объект, например:

Set<Folder> folders = message.getFolders();
   folders.remove(inputFolder);
   folders.add(trashFolder);
   message.setFiles(folders);
MESSAGESDAO.getMessageDAO().save(message);

вам не нужно устанавливать обновленный объект в родительский объект:

message.setFiles(folders);

Просто сохраните свой родительский объект, например:

Set<Folder> folders = message.getFolders();
   folders.remove(inputFolder);
   folders.add(trashFolder);
   // Not set updated object here
MESSAGESDAO.getMessageDAO().save(message);

Ответ 4

В моем случае я копировал и вставлял код из других классов, поэтому я не заметил, что код получателя был написан плохо:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "credito")
public Set getConceptoses() {
    return this.letrases;
}

public void setConceptoses(Set conceptoses) {
    this.conceptoses = conceptoses;
}

Все ссылки концепций, но если вы посмотрите на get, напишите letrases

Ответ 5

Чтение в Интернете причины этой ошибки также может быть ошибкой спящего режима, как обходной путь, который, по-видимому, работает, нужно поставить a:

session.clear()

Вы должны очистить после получения данных и до фиксации и закрытия, см. пример:

//getting data
SrReq sr = (SrReq) crit.uniqueResult();
SrSalesDetailDTO dt=SrSalesDetailMapper.INSTANCE.map(sr);
//CLEAR            
session.clear();
//close session
session.getTransaction().commit();
session.close();
return dt;

Я использую это решение для выбора базы данных, для обновления или вставки я не знаю, может ли это решение работать или может вызвать проблемы.

Моя проблема равна 100% от этого: http://www.progtown.com/topic128073-hibernate-many-to-many-on-two-tables.html

Ответ 7

Позвольте мне ясно объяснить, что это за ошибка,

Позвольте мне начать с примера,

рассмотреть объект

public class foo{
private<user> user;
/* with getters and setters */
}

И рассмотрим класс бизнес-логики

class foo1{
.
.
List<User> user = new ArrayList<>();
user = foo.getUser();
.
.
}

Здесь пользователь и foo.getUser используют одну и ту же ссылку. при сохранении двух ссылок возникает конфликт.

Правильное использование должно выглядеть следующим образом:

class foo1 {
.
.
List<User> user = new ArrayList<>();
user.addAll(foo.getUser);
.
.
}

Это позволяет избежать конфликта