2009-06-17 2 views
3

확장 된 영구 컨텍스트를 사용하고 있습니다. 객체에 대해 일대 다 관계를 지연로드 할 수 있고 또한 "병합"하기 전에 SELECT가 필요하지 않기 때문에 지속 컨텍스트 persistent context를 가진 객체.JPA/Hibernate 쿼리가 부실 결과를 반환합니다.

내가 가진 DummyObject 있습니다

  1. A "최근 업데이트"날짜 필드를

  2. 이 개체는 모든 5 업데이트되는

한 많은 관계 초 단위로 em.merge(DummyObject) 호출. 다른 JVM에서

, 나는 DummyObject 내가이 쿼리마다 5초를하고있는 중이 야 다음

em.createQuery("from DummyObject").getResultList(); 

같은 통화를하고 쿼리.

문제는 Hibernate가 올바른 SQL 문 (로그온 할 때 문이있을 때)과 데이터베이스가 생성 되어도 연속적인 호출 이후에 쿼리의 결과가 모두 첫 번째 쿼리의 타임 스탬프를 가지고 있다는 것입니다 업데이트를 올바르게 받고 있습니다 (확인했습니다).

@Version을 사용하여 모든 종류의 낙관적 잠금을 사용하지 않으려 고 시도했습니다.

  1. 내가 나를 게으르게 ONE-많은로드를 허용하지 않습니다 TRANSACTIONAL (무언가에 PersistentContextType을 변경 : 다른 것은 때이 제대로 작동 않는다는 것입니다

    을 (설명 참조) 관계)

  2. 위의 쿼리를 수행하기 전에 EntityManager.clear() 호출을 수행합니다. 날 편애로로드 관계).

왜 내 쿼리가 부실 데이터를 반환합니까? 아니요 두 번째 수준의 캐싱 또는 쿼리 캐싱을 사용할 수 있습니다.

내가 잘못 했나요? query.setHint (,)를 통해 설정할 수있는 것이 있습니까?

은 어쩌면 내가 제대로 TRANSACTIONAL 대 " 확장"이해가 안 돼요.

+1

은 버전으로 매핑 된 마지막 업데이트입니까? – Surya

+0

방금 ​​해봤습니다. 작동하지 않았다. 또한 명시적인 "버전"필드를 추가하고 @Version으로 주석을 달아 보았습니다. 또한 작동하지 않았다. – systemoutprintln

+0

은 lastUpdated를보고있는 equals 및 hashcode입니까? em.createQuery() 결과에 속하지 않는 추가 객체가 보입니까? – zmf

답변

0

가져 오기 전에 flush()를 시도 했습니까?

+0

방금 ​​시도 ... 작동하지 않았다. 그래도 고마워. – systemoutprintln

+0

매번 객체를 다시 페치하거나 지연된 참조를 사용하고 있습니까? 새로운 데이터가 나타나기 전에 개체를 다시 가져와야하는 문제가있었습니다. – Jesse

+0

나는 당신이 의미하는 것을 이해하는지 잘 모르겠습니다. 위의 쿼리를 5 초마다 실행하고 있는데 쿼리에서 얻은 결과가 오래되었습니다. 이것은 실제 구현보다 "테스트"사례에 가깝습니다. 근본적으로 내 문제는 EXTENDED 컨텍스트 유형을 사용하고 느슨하게 관계를로드 할 수 있기를 원합니다. 그러나 작동하지 않는 것은 쿼리가 항상 오래된 결과를 반환한다는 것입니다. – systemoutprintln

0

흥미 롭습니다. 나에게 당신의 영속 컨텍스트의 엔티티 인스턴스가 질의의 결과로 업데이트되지 않는 것 같다. 이는 의도적으로 설계되었을 수 있습니다. 쿼리를 실행하여 실수로 로컬 변경 사항을 덮어 쓸 수 있습니다.

JPA에는 단일 인스턴스를 분리 할 수있는 방법이 없습니다. 전체 컨텍스트를 지우거나 컨텍스트를 지우지 않습니다. 그래서 그것은 가능한 해결책도 아닙니다.

PersistanceContext 클래스에서 사용할 수있는 refresh() 방법이 데이터베이스에서 변경되어 그에 따라 엔티티 인스턴스를 업데이트합니다. 그러나 실제 구현에서 이것이 어떻게 적용되지 않을지를 알 수 있습니다. 그래서 제 대답은 다음과 같이 밝혀졌습니다 : 아마 그걸 작동시킬 수는 없을 것입니다.

+0

그래, 나는 반환 된 결과 집합을 반복하고 각 객체에서 "새로 고침"을하는 것을 살펴 봤지만 큰 결과 집합은 우습다. – systemoutprintln

+0

목록의 콘텐츠가 동일하게 유지됩니까 (즉, 새로운 개체를 얻지 않거나 오래된 개체를 삭제하지 않습니까)? –

+0

목록의 각 객체에서 refresh()를 수행하지 않으면 목록의 내용이 동일하게 유지됩니다. – systemoutprintln

1

하이버 네이트 세션은 영속 객체를 캐싱하고있다. 따라서 하나의 JVM (A)에서 수정하고 다른 JVM (B)에서 읽기 때문에 변경 사항을 보려면 B의 세션을 새로 고쳐야합니다. 새 세션을 열거 나 영구 객체를 축출/새로 고침 할 수 있습니다. 또한 문제를 처리 할 수있는 두 JVM에서 세션을 복제 할 수 있습니다. 또는 쿼리를 변경하여 필요한 'DummyObject'조각 만 반환하고 필요할 때 영구 개체를 읽을 수 있습니다. 또한 무국적 세션을 시도 할 수도 있습니다.

관련 문제