2012-08-28 3 views
0

필자는 Visual Paradigm을 사용하여 Java 프로젝트를 개발하고 있습니다. 비주얼 패러다임은 Hibernate를 사용하고있다. Genady RMI를 추가하기 전까지 프로젝트가 잘 돌아가고있었습니다. 나는 또한 RMI를 사용해야한다.Hibernate + RMI가있는 "No session or session was closed"

서버 측에서는 데이터베이스에 대한 모든 쿼리를 관리하는 MainDb가 있으며 클라이언트 측에는 RMI Remote를 구현하는 UserWindow 및 AdminWindow 클래스가 있습니다. 이 두 클래스는 RMI를 통해 MainDb 객체를 가져옵니다. 나는 서버와 클라이언트를 실행 해요

, 나는 오류 게으른 초기화에 관련된 예외를 가지고있다 "아무 세션이나 세션이 종료되지 않았다"

failed to lazily initialize a collection of role: dcl.UsuarioRegistrado.ORM_TieneVideosFavoritos, no session or session was closed. 

를 지금까지 내가 아는 한, Hibernate는 dcl.UsuarioRegistrado 객체가 생성 된 다른 세션을 사용하고있다. 문제는 PersistentManager 클래스가 getSession() 만 제공하기 때문에 세션을 관리하지 않는다는 것입니다. PersistentManager 클래스는 VisualParadigm이 Hibernate를 관리하기 위해 제공하는 클래스이다.

모든 엔티티를 lazy = "false"로 구성하려고했지만 일부 엔티티의 속성이 올바르게로드되지 않아 그 결과가 나 빠졌습니다. 예를 들어 "Topic"개체가 "TopicName"String 속성과 함께로드되어 null로 설정되었습니다.

그래서 동일한 세션을 유지하려면 어떻게해야합니까?

미리 감사드립니다. 매우 불쌍하지만 내 불쌍한 영어입니다. 상황을 영어로 설명하기가 어렵습니다. 다시 한번 감사드립니다.

+0

'PersistentManager.getSession()'반환 세션을 사용하여'sessionFactory.getCurrentSession()'또는'는 SessionFactory.openSession()'? –

+0

C3P0 연결 풀을 사용하고 있습니까? 그렇다면 문제를 해결할 수 있는지 확인하십시오. 난 최대 절전 모드 전체 struts2 플러그인과 비슷한 문제가 있었다. – Resh32

+0

@ Resh32 C3P0을 사용하고 있습니다. 에서 속성을 제거하는 것을 비활성화 할 수 있습니까? – honnix

답변

1

이것은 일반적인 문제입니다. 엔티티에 콜렉션이 있으면, Hibernate는 인스턴스에 "Hibernate-aware"콜렉션을 삽입 할 것이다. 따라서 목록 대신 현재 세션 ("현재"= 엔티티가로드 된 세션)을 기억하는 무언가를 얻습니다.

이유는 세션 == 데이터베이스 트랜잭션입니다. 만약 Hibernate가 새로운 세션을 사용하여 관련된 엔티티를로드한다면, 새로운 엔트리, 업데이트 된 행을 보거나 부모 엔티티를로드했을 때 여전히 존재하는 행들이 삭제 되었기 때문에 에러가 발생할 수있다. 그것은 엉망이 될 것입니다.

Hibernate는 원래 세션을 사용하여 관련된 모든 엔티티를로드합니다. 그러나 코드는 일반적으로 다르게 작동합니다. 한 부분에서는 엔티티를로드합니다. 세션이 종료되었습니다. 그렇다면 전혀 관련이없는 부분에서 children -> error를로드하려고 시도합니다.

  1. 해제 지연로드 :

    는 세 가지 솔루션이 있습니다. 이것은 종종 작동하지 않습니다 (로드가 너무 많고 너무 느립니다). 그러나 오류가 있어서는 안됩니다. 코드에 버그가 숨어있을 수 있습니다.

  2. 엔티티를로드 할 때 각 컬렉션에서 첫 번째 엔티티를 가져옵니다. 그러면 컬렉션이 올바르게 초기화됩니다. 여기에있는 장점은 관련 인스턴스를로드 할시기와 지연로드를 위해 Hibernate를 사용할시기를 코드에서 결정할 수 있다는 것입니다.

    필요한 관계 만로드 할 수도 있습니다. 그래서 이것은 종종 이전의 문제를 해결합니다. 단점은 다른 코드가 여러분의 엔티티 인 을 미리 사용하는 방법을 알아야한다는 것입니다.. 이것은 종종 어렵거나 심지어 불가능합니다.

  3. Session.refresh()을 사용하여 새 세션을 만들고이 새로운 세션에 기존 개체를 "연결"할 수 있습니다. 여기서주의해야합니다. 새로 고침하고 오래된 객체를 혼합하면 오류가 발생합니다.

+0

나는 옵션 1을 다시 시도했고, 그 코드에 오류가 있었다. 이 오류를 해결하고 몇 가지 다른 오류가 발생합니다. 그것들은 기본적으로 "동일한 식별자를 가진 다른 객체"입니다.이 객체를 해결하는 방법을 알지 못합니다. – honnix

+0

여기에는 여러 가지 이유가있을 수 있습니다. 내 대답을 수락하고 정확한 질문과 스택 추적을 추가 한 내용을 새 질문으로 게시하십시오. –