2009-07-08 6 views
0

방금 ​​NHibernate를 사용하기 시작했고 제대로 해결할 방법이 확실하지 않은 몇 가지 문제가 있습니다.NHibernate 세션 - Windows 응용 프로그램에서 세션을 처리하는 일반적인 방법은 무엇입니까?

나는 CUD와 두 가지 검색 방법을 포함하는 일반 저장소를 만들기 시작했습니다. 이러한 각 메소드는 DB 작업 중 별도의 세션 (필요한 경우 트랜잭션)을 엽니 다. 이렇게 할 때 문제는 (내가 말할 수있는 한) 관련된 콜렉션/객체의 게으른 로딩을 이용할 수 없다는 것입니다.

유창한 매핑에서 거의 모든 엔티티 관계가 .Not.LazyLoad()이므로 주어진 유형의 모든 엔티티 목록을 요청하면 전체 데이터베이스가로드됩니다. 내가 틀렸다면 난 아직 완전한 안돼서 원인이 올 때

이 ', 정정 해줘 NHibernate에 :)

이를 방지하기 위해 수행하는 가장 일반적인 무엇

? 프로그램이 실행되는 동안 하나의 전역 정적 세션을 유지합니까? 그렇지 않으면 어떻게해야합니까?

var person = m_PersonRepository.GetById(1); // works fine 

var contactInfo = person.ContactInfo; // Throws exception with message: 

// failed to lazily initialize a collection, no session or session was closed 

답변

3

귀하의 질문은 실제로 캐싱 및 재사용을 반대하는 귀결 인격을 얻을 수있는 저장소를 사용

public T GetById(int id) 
{ 
    using (var session = NHibernateHelper.OpenSession()) 
    { 
     return session.Get<T>(id); 
    } 
} 

:


저장소 코드의 일부. 한 세션에서 Foo 객체를로드하면 나중에 그 객체를 유지하고 나중에 Bar 속성을 게으른로드 할 수 있습니까?

각 ISession 인스턴스는 작업 단위 (UOW)를 나타 내기 위해 설계되었으며, 작업 단위 내에서 오브젝트를 여러 번 검색 할 수 있지만 단일 데이터베이스 히트 만 가질 수있는 1 차 레벨 캐시가 제공됩니다. 스레드로부터 안전하지 않으므로 WinForms 응용 프로그램에서 정적 개체로 사용해서는 안됩니다.

로드 된 세션이 삭제되었을 때 개체를 사용하려면 Session.SaveOrUpdate (개체) 또는 Session.Update (개체)를 사용하여 개체를 새 세션에 연결해야합니다.

chapter 10 of the Hibernate documentation에서 설명한 모든 내용을 확인할 수 있습니다.

비효율적이면 2 차 캐싱을 살펴보십시오. 이것은 ISessionFactory 레벨에서 제공됩니다. 세션 팩토리는 정적 일 수 있으며, 2 차 레벨 캐싱을 사용하면 데이터의 대부분을 메모리 내 캐시로 효과적으로 빌드 할 수 있습니다. 2 차 수준의 캐싱은 데이터를 업데이트하는 기본 서비스가없는 경우에만 적합합니다. 모든 데이터베이스 업데이트가 NHibernate를 통과하면 안전한 것입니다. 당신은 오히려 작업 단위보다 얻을 하나의 데이터베이스를 사용하는 - 코드의 빛

편집 세션 사용이 잘못된 수준에

기록했다. 이 경우 사용자의 GetById 메소드가 사용하는 세션을 가져와야하며 세션 인스턴스는 상위 레벨에서 관리해야합니다. 또는 선호하는 경우 PersonRepository 클래스에서 세션을 관리해야하며 각 작업 단위에 대해이 유형의 객체를 인스턴스화하고 처리해야합니다.

귀하가 이미 가져온 오류 메시지는 더 이상 세션을 지연로드하는 데 사용할 세션이 없기 때문입니다. 이미 폐기했기 때문입니다.

+0

답변 해 주셔서 감사합니다. 문서에서 챕터를 읽었지만 두 번째 문장에서 의미하는 바를 아직도 이해하지 못합니다. 게으른로드 속성에 액세스해야하는 경우 세션을 유지해야한다는 의미입니까? 질문에 저장소 코드를 추가하겠습니다. – l3dx

+0

물론 - 질문에 약간의 문맥을 추가하면 답변에 좀 더 구체적으로 설명 할 것입니다. –

+0

니스, 정말 고마워! +1 나는 내 저장소를 리팩터링 할 것입니다. :) 내 이해는 실제 응용 프로그램에서 세션/db 항목을 "계층화"해야한다는 것입니다. 추가적으로 저장소에서 제거한다면 어디에 놓을까요? – l3dx

관련 문제