IT story

컬렉션 org.hibernate.HibernateException에 대한 공유 참조를 찾았습니다.

hot-time 2020. 12. 29. 07:52
반응형

컬렉션 org.hibernate.HibernateException에 대한 공유 참조를 찾았습니다.


이 오류 메시지가 나타납니다.

오류 : 컬렉션에 대한 공유 참조를 찾았습니다 : Person.relatedPersons

내가 실행하려고 할 때 addToRelatedPersons(anotherPerson):

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

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

내 도메인 :

Person {

 static hasMany = [relatedPersons:Person];

}

왜 이런 일이 발생하는지 아십니까?


Hibernate는 동일한 컬렉션 참조를 공유하는 하나 이상의 엔티티 인스턴스를 유지하려고 시도 할 때이 오류를 표시합니다 (즉, 컬렉션 동등성과 대조되는 컬렉션 ID).

이 같은 의미합니다 콜렉션 즉 -,하지 콜렉션 요소 relatedPersons모두를 personanotherPerson동일해야합니다. 엔티티가로드 된 후 해당 컬렉션을 재설정하고 있습니까? 아니면 동일한 컬렉션 인스턴스로 두 참조를 모두 초기화 했습니까?


나는 같은 문제가 있었다. 제 경우 문제는 누군가 BeanUtils를 사용하여 한 엔티티의 속성을 다른 엔티티로 복사했기 때문에 동일한 컬렉션을 참조하는 두 엔티티가 생겼습니다.

이 문제를 조사하는 데 시간을 할애했기 때문에 다음 체크리스트를 권장합니다.

  • 같은 시나리오를 찾으 entity1.setCollection(entity2.getCollection())getCollection(getCollection은 () 컬렉션의 새로운 인스턴스를 반환하는 경우, 당신은 걱정할 필요가 없습니다) 반환 컬렉션에 내부 참조.

  • 경우 봐 clone()제대로 구현되었습니다.

  • 를 찾으십시오 BeanUtils.copyProperties(entity1, entity2).


연습에 대한 설명. 객체를 저장하려는 경우, 예 :

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);

이 오류의 원인을 온라인으로 읽는 것도 최대 절전 모드 버그수 있습니다. 작동하는 것처럼 보이는 해결 방법 은 다음과 같습니다.

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


제 경우에는 다른 클래스의 코드를 복사하여 붙여 넣었으므로 getter 코드가 잘못 작성된 것을 알지 못했습니다.

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

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

모든 참조는 개념 이지만 get을 보면 letrases 라고 말합니다 .


I too got the same issue, someone used BeanUtils.copyProperties(source, target). Here both source and target, are using the same collection as attribute.

So i just used the deep copy as below..

How to Clone Collection in Java - Deep copy of ArrayList and HashSet


I faced similar exception in my application. After looking into the stacktrace it was clear that exception was thrown within a FlushEntityEventListener class.

In Hibernate 4.3.7 the MSLocalSessionFactory bean no longer supports the eventListeners property. Hence, one has to explicitly fetch the service registry from individual Hibernate session beans and then set the required custom event listeners.

In the process of adding custom event listeners we need to make sure the corresponding default event listeners are removed from the respective Hibernate session.

If the default event listener is not removed then the case arises of two event listeners registered against same event. In this case while iterating over these listeners, against first listeners any collections in the session will be flagged as reached and while processing the same collection against second listener would throw this Hibernate exception.

So, make sure that when registering custom listeners corresponding default listeners are removed from registry.


Consider an entity:

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

And consider an Business Logic class:

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

Here the user and foo.getUser() share the same reference. But saving the two references creates a conflict.

The proper usage should be:

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

This avoids the conflict.

ReferenceURL : https://stackoverflow.com/questions/1692871/found-shared-references-to-a-collection-org-hibernate-hibernateexception

반응형