2012-03-15 3 views
1

나는 user와 credit_card 엔티티를 가지고 있는데, 사용자는 credit_card 콜렉션을 가지고있다. 두 엔티티에 대한 기본 키는 byte []입니다.byte []가 기본 키인 session.buildLockRequest의 HibernateException

첫 번째 세션 : - 새 세션을 열었습니다. - 실제로 DB로 이동하여 user + credit_cards를 가져 오는 users 테이블에 대한 조건 쿼리를 수행하고 마지막으로 userObj라고하는 사용자 객체가 있습니다. - 세션을 닫습니다.

두 번째 세션 : - I 다른 세션을 열었습니다. - session.buildLockRequest (LockOptions.NONE) .lock (userObj);을 호출하려고합니다.

이제 분리 된 개체를 다시 시도합니다 최대 절전 모드, 그러나 나는 다음과 같은 오류가 발생합니다 :

org.hibernate.HibernateException: reassociated object has dirty collection reference 
at org.hibernate.event.def.OnLockVisitor.processCollection(OnLockVisitor.java:71) 
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:122) 
at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:83) 
at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:77) 
at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:144) 
at org.hibernate.event.def.AbstractReassociateEventListener.reassociate(AbstractReassociateEve ntListener.java:101) 
at org.hibernate.event.def.DefaultLockEventListener.onLock(DefaultLockEventListener.java:82) 
at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:774) 
at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:766) 
at org.hibernate.impl.SessionImpl.access$600(SessionImpl.java:156) 

내가 최대 절전 모드 코드를 디버깅하기 위해 노력하고, 그 최대 절전 모드가 전달 된 객체의 여부를 확인하려고 발견 collection (credit_cards)은 실제로 user1 (user1)이 소유합니다.

는 이 와 평등에 대한 검사처럼

그래서 어딘가 깊은 최대 절전 모드에서 코드 아래로 보인다 는 전달 된 개체의 기본 키의 방법을 (사용자 1 인)에 해당하고 다른는 스냅 샷 개체를 호출하는 어떤 객체 . byte []는 본질적으로 배열이므로 equals 검사에서 실패하고 위의 오류가 발생합니다. 위의 작업을 한 세션에서 수행 할 수 있음을 알고 있지만 이는 단지 시나리오에 불과합니다.

기본 키로 Long/Integer를 사용했지만 동등성 검사를 통과 했으므로 정상적으로 작동합니다.

최대 절전 모드 버전 : 3.6.9.Final (내가뿐만 아니라 4.1.1.Final 버전을 살펴보고했지만,이 오류가 발생합니다 파일/코드가 변경되지 않습니다) DB : SQL 서버

최대 절전 모드에서 문제가 되나요? 아니면 잘못된 것이 있습니까?

+0

동료가 최대 절전 모드 버그로보고했습니다. [https://hibernate.onjira.com/browse/HHH-7180](https://hibernate.onjira.com/browse/HHH-7180) – sheoran

답변

1

바이트 [] 대신 문자열을 기본 키로 사용하십시오. 그것은 동일한 값을 운반 할 수 있고 그것을 가 절전 문제가되지 방법

String myId = new String(bytes); 

myId.getBytes(); 

동일 통과 할 것이다.

+0

예 , 나는 그것을 시도하고 내가 잘 사용하는 경우 긴,하지만 기본 키로 바이트 [] 사용하여이 문제의 모든 솔루션을 무엇입니까? – sheoran

+0

no. String을 대신 사용하십시오 – kromit

1

최대 절전 모드에서는 문제가되지 않습니다. ID 클래스는 hashCode를 구현하고 equals를 올바르게 구현해야합니다. byte[]은 유효하지 않으므로 유효한 ID 클래스가 아닙니다. byte []를 ID로 사용하는 것은 IMO입니다. 이것은 정말 나쁜 생각입니다. Long은 정말 좋은 아이디어입니다. 바이트 배열을 유지하고 싶다면 사용자 정의 유형으로 포장하거나 Base64 또는 Hex 인코딩을 사용하여 String으로 변환하십시오.

+0

나는 동의하고 byte []를 사용하는 것이 모범 사례가 아닐 수도 있음을 알고 있습니다. 하지만 내 질문에 왜 이런 종류의 상황에 대해 byte []가 지원되지 않거나 최대 절전 모드에서 지원되지 않는/권장되지 않는 유형의 목록이 있습니까? – sheoran

+0

ID 클래스는 equals 및 hashCode를 올바르게 구현해야합니다. 그것은 규칙입니다.데이터베이스에서 같은 값을 나타내는 두 개의 다른 인스턴스는 같아야하며 같은 hashCode를 가져야합니다. –

관련 문제