2012-07-05 3 views
0

매핑 된 복합 식별자없이 복합 ID를 선언하는 객체에 대한 세션을 수행하려고합니다.
사용 된 최대 절전 모드 버전은 3.5.5입니다.composite-id로 Session.get() 이상한 동작을 해결하려면?

가져 오기 코드는 일반적이며 실제 데이터를 포장 컨테이너 객체를 읽는 ID에 대한 메타 데이터를 참조해야하므로

ClassMetadata metadata = 
      session.getSessionFactory().getClassMetadata(wrapper.getDomainClass()); 
Serializable id = metadata.getIdentifier(wrapper, EntityMode.POJO); 
return session.get(wrapper.getDomainClass(), id, LockOptions.UPGRADE); 

코드는 실제 매핑에 대해 아무것도 알지 못한다. 매핑은 다음과 같이 정의되는 경우

는 : 복합 클래스 식별자없이

<hibernate-mapping default-access="field"> 
    <class name="Wrapper" 
     entity-name="Data" 
     table="DATA"> 
    <composite-id> 
     <key-property name="identifier" column="identifier" /> 
     <key-property name="version" column="version" /> 
    </composite-id> 

    <component name="domainObject" class="Data"> 
     <property name="source" column="source" /> 
    </component>      
    </class> 
</hibernate-mapping> 

, ID는 물체 자체와 같고 래퍼 기준과 동일하다.
데이터베이스에서 객체를 가져 오는 대신 session.get()을 수행하면 같은 객체가 아니라 객체의 동일한 인스턴스 인 id에 전달 된 것과 동일한 객체가 반환됩니다.
업데이트 : 실제로 session.get()은 in 데이터베이스에서 객체를로드하고 전달 된 객체를 반환합니다. 처음에는 로딩을 건너 뛰고 있다고 생각했습니다. 내가 지금까지 매핑 소개합니다되는 복합 식별자 변경 매핑을 발견

솔루션 :

<hibernate-mapping default-access="field"> 
    <class name="Wrapper" 
     entity-name="Data1" 
     table="DATA_1"> 
    <composite-id class="SurrogateKey" mapped="true"> 
     <key-property name="identifier" column="identifier" /> 
     <key-property name="version" column="version" /> 
    </composite-id> 

    <component name="domainObject" class="Data"> 
     <property name="source" column="source" /> 
    </component>      
    </class> 
</hibernate-mapping> 

대체 키는 두 개의 필드와 객체로 정의하고 필요에 따라/해시 코드를 동일합니다.
metadata.getIdentifier()에 의해 반환 된이 변경 ID는 SurrogateKey의 인스턴스이며 session.get()은 데이터베이스에서 객체를 가져옵니다 (있는 경우).

매핑 수정의 문제

식별자에서 id.identifier 그에게 기준과 HQL 변화에 대한 속성 이름이 실제로 기존의 코드를 많이 파괴된다는 것이다. 나는 순간에 탐구하고 있습니다

상황은 다음과 같습니다

  1. (나는 이것이 낙담 연습 알고 있지만, 변화의 양이 필요한 아이디 클래스를 선언하지 않고) (에 Session.get을 작동 할 수있는 방법이 있나요 금지 될 수 있음)?
  2. id를 추가하지 않고 이전처럼 프로퍼티를 처리하기 위해 hibernate에 알려줄 수 있습니까? 그들 앞에서?
  3. 최대 절전 모드를 v4로 업그레이드하십시오 (종속 프로젝트 및 승인 프로세스로 인해 쉽지 않음).
  4. 다른 옵션/해결 방법이 있습니까?

지금까지 나는 단지 일 위에서 설명한 솔루션을 관리했습니다,하지만 난 덜 침입 한 찾고 있어요 및 관련 문서에 대한 단서, 제안, 포인터를 감사하겠습니다.

답변

1

첫 번째 코드 스 니펫에 wrapper은 무엇입니까? 첨부 된 엔티티 인 경우 (분명히) session.get()은 동일한 식별자를 가진 첨부 된 엔티티를 반환하며 식별자는 엔티티 자체이므로 제공된 첨부 엔티티를 반환합니다. 세션에는 항상 주어진 엔티티 인스턴스가 하나만 있습니다.이제

, 당신의 질문에 대답하기 : 예상대로

  1. AFAIK, 그것은 작동합니다.
  2. No.
  3. 이 질문이 있습니까?
  4. 가장 좋은 해결 방법은 올바른 작업을 수행하고 복합 식별자 사용을 중지하는 것입니다. Hibernate에서 권고 한대로 단일 컬럼, 자동 생성 ID를 사용하면 모든 것이 훨씬 간단해질 것이다.
+0

get이 완료 될 때 래퍼가 세션에 연결되지 않습니다. 그것은 적어도 우리가 대체하고 싶은 객체 키를 가지고 있습니다. 이전 버전은 데이터베이스에 있거나 동일한 세션에 저장 될 수 있습니다. 이것은 일괄 저장/업데이트 프로세스이며 id가 외부 시스템에 의해 생성되기 때문에 자동 생성 된 ID는 옵션이 아닙니다. 우리가 그들을 사용한다면, 우리는 질의를 수행하고 일괄 적으로 객체를 수동으로 상호 연관시켜야 할 것입니다. 1이 연결된 엔티티에 대해서만 올바른 동작을하지만 분리 된 엔티티에 대해서는 올바른 동작을하는 경우 올바르게 보이지 않으며 매핑 된 키와 매핑되지 않은 키가 다른 경우 1이 다릅니다. – aliher

+0

주석을 사용하면 두 번째 질문에서 엔티티의 여러 필드를 @Id로 매핑하고 동일한 속성 이름과 유형을 가진 ID 클래스를 지정할 수 있습니다. XML 매핑이 가능한지 여부를 모릅니다. –

+0

초기 게시물을 업데이트하고 솔루션을 게시했습니다. 지금 내게 동면하는 버그처럼 보입니다. 세션은 인스턴스 생성자의 동작의 일부 측면을 고려하지 않습니다. – aliher

0

의미있는 객체를 session.get() 메소드의 id로 사용하면 문제가 발생합니다.

session.get()에는 부작용이 있으며 PojoInstantiator.instantiate() 내부에서 발생하는 인수가 수정됩니다. 로드시, id 클래스가 매핑 클래스와 동일하다는 것을 hibernate가 감지하면 인스턴스 생성을 건너 뛰고 새로운 인스턴스를 인스턴스화하는 대신 method에 전달 된 id 객체를 사용합니다. 이 개체는 데이터베이스에서 기존 필드를 덮어 씁니다.

메타 키가 매핑되지 않은 경우 metadata.getIdentifier()가 객체를 반환하는 경우 솔루션은 객체의 복제본을 만드는 것입니다. 그 클론은 수화되어 get()에 의해 반환 될 것입니다.

관련 문제