2010-01-07 3 views
0

나는 서버 측에서 Hibernate를 사용하여 GWT 애플리케이션을 작성하고있다. 지금 당장은 최소한의 코드로 GWT 애플리케이션의 클라이언트 측에 내 객체를 전송하는 정확한 방법에 대해 혼란 스럽다. 내 도메인 모델 [1]에서 클래스의 양을 두 배로하는 것을 피하기 위해 Gilead를 사용하고 있습니다.Hibernate, GWT, Gilead : 세션, 트랜잭션, 캐시

먼저 내 질문은 세션과 트랜잭션을 여는 방법입니다. 처음에, 나는 모든 RPC 서버 호출에 이런 짓을 :

// begin rpc call 
getCurrentSession 
beginTransaction 
// ...do stuff 
commit 
// session is automatically closed 
// end rpc call 

이 열리고 모든 RPC 호출에 대한 세션을 종료하기 때문에,이 또한 데이터베이스 서버마다에 대한 새 연결을 만들 수 있습니까?

어쨌든, 최대한 빨리, 나는이 패턴을 사용하여 다음과 같은 예외가 느리게로드 컬렉션을 사용하여 시작과 같이 길르앗 컬렉션을 직렬화 할 수있는 기회를 얻기 전에

org.hibernate.HibernateException: collection is not associated with any session 
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:449)` 

이 세션이 닫혀 있는지 나에게 보인다 개체 및 이로 인해 예외가 발생합니다. 나는이 일을하고있을 때

openSession 
// begin rpc call 
beginTransaction 
// ...do stuff 
commit 
// end rpc call 

// next rpc call 
beginTransaction 
// ...etc 

하지만, 난 :

그래서 내가 명시 적으로 모든 트랜잭션 후 자동으로 종료 할 수없는 그래서 같은 세션 나 자신을 열어이 문제를 해결하기 위해 시도 Session 객체 캐시와 관련된 모든 종류의 펑키 한 동작을 볼 수 있습니다. 한 가지, createQuery(). executeUpdate()는 세션 캐시를 무효화하는 것처럼 보이지 않지만 다양한 사이트에서 읽어야합니다. session.flush(), session.clear() 등의 다양한 순열을 호출하여 세션 캐시를 무효화하려고 시도했을 때 Gilead 또는 Beanlib 내부의 직렬화에서 다음 오류는 "ClassCastException : null"이었습니다 . 내가 좋아하는 오류를 받고 있어요

clients get an object from the server 
client modifies object 
client sends object back 
server calls session.saveOrUpdate() 

"동일한 식별자를 가진 다른 객체하면 세션 캐시에 이미"나는 이런 식으로 뭔가를 시도하고 다른 일에 대해서는

.

이런 종류의 것을 설정하는 올바른 방법은 무엇입니까? 내 세션의 범위를 어떻게 지정해야하며 캐시를 어떻게 처리해야합니까? 나는 이것을 시험해보고 그것에 문제가있는 유일한 사람이라고 상상할 수는 없지만, 훌륭한 가이드는 어려워 보인다.

[1]

+0

당신이 가지고있는 마지막 문제에 관해서 : "동일한 식별자를 가진 다른 객체는 이미 세션 캐시에 있습니다"라고 saveOrUpdate를 사용할 때 merge를 사용해야합니다. 동일한 객체가 없다고 가정합니다. 식별자를 세션 캐시에 저장하고 DB에 그러한 식별자가있을 수 있습니다 (따라서 orUpdate). 병합을 사용해야하는 세션에서 여전히 클라이언트에 객체 snet이 있습니다. 참조 : http://www.stevideter.com/2008/12/07/saveorupdate-versus-merge-in-hibernate/ – Ittai

답변

0

저는 Gilead를 사용하지 않기 때문에 문제의 일부가 될 수 있지만 ThreadLocal 세션을 사용합니다. 각 rpc 호출에서 최종 반환 전에 항상 ThreadLocal 세션을 닫는 메서드에서 논리를 래핑합니다. 해당 스레드가 처음 요청 될 때 세션이 열립니다.

그러나 세션을 닫기 전에 프록시를 완전히 초기화해야합니다.대부분의 경우, GWT는 세션이 닫힌 후 POJO를 직렬화하려고 시도하고 프록시 또는 게으른 콜렉션에 도달하면 우연히 초기화하려고 시도합니다. 개인적으로, 나는 POJO를 다른 객체로 복사하는 것에 대한 공격을 받거나, 어떤 필드가 직렬화되고 컬렉션에 size()를 호출하는 등의 방식으로 미리 '터치'할 것인지 정확하게 알고 있는지 확인합니다.

직렬화 후 rpc 스레드가 완료되기 전에 코드를 실행할 수있는 GWT 후크가 있으면 좋을 것입니다. 그것에 대해

관련 문제