2010-12-08 2 views
2

NHibernate 프로젝트에서 작업 중이며 이전에 컬렉션을로드하는 데 문제가있는 곳 (http://stackoverflow.com/questions/4213506/c-hibernate-criteria-loading- 컬렉션), 이제는 데이터 사용에 문제가 있습니다.C# 데이터를 사용할 때 Spring LazyInitializationException이있는 NHibernate

나는 NHibernate와 Spring.Net 프레임 워크와 함께 C#을 사용하고 있는데, 예를 들어 'ordercredit'을로드 한 다음 ordercredit의 객체에 액세스하면 LazyInitializationException이 발생합니다.

[Transaction(TransactionPropagation.Required, ReadOnly = true)] 
public OrderCredit GetOrderCredit(long ordercreditid) 
{ 
    var creditrules = Session.CreateCriteria(typeof(OrderCredit)); 
    creditrules.Add(Restrictions.Eq("Id", ordercreditid)); 
    return creditrules.List<OrderCredit>()[0]; 
} 

내 로컬 컴퓨터에서이 작업을 실행

모든 :

OrderCredit oc = CreditService.getOrderCredit(ordercredit.Id); 

I로드에 사용하는 코드는 DAO 구현을 사용하여 수행됩니다 :

은 내가 OrderCredit을 얻기 위해이 코드를 사용 잘 작동하고, 실제로 그 'ordercredits'의 목록을로드하기위한 것이 었습니다. 그러나 그것은 잘못되었습니다. 그래서 더 간단한 단계를 먼저 시도했습니다.

'OrderCredit'내의 개체는 [OneToMany]로 정의됩니다.

NHibernate.LazyInitializationException : 초기화 [.OrderObject는 # 5496522] 초기화 안되나요 나는 TESTSERVER에 넣어로드 된 OrderCredit의 'OrderObject'개체에 액세스하려고 할 때

, 나는 오류 proxy - 세션 없음. 실패

코드 :

Log.Debug(oc.OrderObject.Name); 

코드 작동 :

Log.Debug(oc.Id); 

이것은 OrderCredit의 일부 개체에 대한 발생,하지만 난 OrderCredit의 속성 필드에 액세스 할 수 있어요 (예를 들어 OrderCredit.Id).

또한 메서드를 호출하는 원래 함수에 데이터를 반환하기 전에 개체에 액세스하면 정보에 액세스 할 수 있으므로 캐시에 액세스 할 수 있습니다.

나는이 문제에 관해 많은 것을 읽었지만, Lazy를 끄는 것처럼, 그러나 그것은 나에게도 (또는 나는 잘못된 곳에서) 그렇게하지 못했다.

나를 가장 좌절시키는 것은 테스트 서버가 아닌 내 로컬 컴퓨터에서 실제로 작동한다는 것입니다. 나는 무엇을 잘못 할 수 있 었는가?

도움이 매우 감사합니다.

1 업데이트 :

I로드 1 ordercredit의 기본 방법을 사용하여, 지금 GenericDao를 사용하고 있습니다. 다음 코드를 사용하여 Id로 1 ordercredit을로드합니다.

OrderCredit oc = GenericService.Load<OrderCredit>(Id); 

나는 ordercredit에 부착 된 개체에 액세스 할 수 있어요 의미 GenericDAO이 다음은,하지만이 종료되지 않거나 세션을 나누기 내부의 코드 :

[Transaction(TransactionPropagation.Supports, ReadOnly = true)] 
public T Load<T>(long id) where T : ISaveableObject 
{ 
    var obj = Session.Load<T>(id); 
    return obj; 
} 

이것은이다 이 질문의 앞 부분에 포함 된 기능과 거의 같은 코드입니다.

저는 세션이 끝날 수있는 것이 무엇인지 모르기 때문에 지금 혼란 스럽습니다. 나중에 작동 할 것이지만 나중에 변경하고 싶습니다. 그래서 함수를 사용하여 전체 컬렉션을 호출하고 for each 루프를 통해 액세스 할 수 있습니다.

현재 'getOrderCredits'함수를 사용하여 OrderCredit 객체의 목록을 가져오고 foreach에서는 Id를 얻고 GenericDao.Load를 사용하여 실제 항목을 가져오고 객체 등을 액세스 할 수 있습니다. . 물론 이것은 이것이 있어야하고 필요로하는 방식이 아닙니다.

이 문제가 해결되면 놀랄 것입니다.

+0

NH 세션을 열고 닫으시겠습니까? 이 오류 메시지는 시도한 지연로드가 발생할 때까지 NH 세션이 닫혔다 고 제안합니다. –

+0

그것은 내가 일하는 프로젝트의 확장판입니다. 트랜잭션은 Hibernate/Spring 트랜잭션 관리자에 의해 다루어진다. 나는 여러 가지 일을 시도해 왔으며, 작은 일을하려고왔다. 내 질문을 편집하고이 정보와 코드를 추가합니다. 내 상황에서 그것이 잘못된 것만 알지는 못합니다. – Honnes

답변

4

사람들이 NHibernate를 사용할 때 공통적으로 발생하는 문제입니다. 때문에 발생 : 당신은 세션을 열

  1. 당신은
  2. 당신은 세션을
  3. 을 닫고 다른 엔티티 당신은 당신의 참조 된 엔터티의 속성에 액세스하려고를 참조 데이터베이스에서 엔티티를로드
  4. Hibernate는 부모 엔티티를로드 한 동일한 세션을 사용하여 데이터베이스에서 느슨하게 엔티티를로드하려고 시도합니다.
  5. 세션이 닫혀 있으므로 NHibernate는 woah와 같은 예외를 throw합니다.

당신은 여기에 몇 가지 옵션이 있습니다

  1. 은 바람직하게는 당신에게 엄격한 제어를 줄 것이다 작업 패턴의 단위, 같은 것을 사용하여, 더 이상 공개 세션을 유지합니다. 당신은 쿼리 할 때
  2. 간절히 당신의 참조 된 개체를로드 :

를 귀하의 경우에는 봄 당신을 위해 거래를 관리하고로 2 옵션이 아마 가장 빠른/가장 쉬운 해결책이다. 당신이 OrderCredit를로드 할 때

var creditrules = Session.CreateCriteria(typeof(OrderCredit)); 
creditrules.Add(Restrictions.Eq("Id", ordercreditid)) 
    .SetFetchMode("OrderObject", FetchMode.Eager); 

이것은 OrderObject로드됩니다.

+0

입력 해 주셔서 감사합니다! 나는 그 프로젝트에서 더 이상 일하지 않기 때문에 더 이상 테스트 할 수 없다고 덧붙여 야합니다. 그러나 당신의 의견을 고맙게 생각합니다. 나는 그것을 테스트 할 수 없기 때문에 대답을 인정 된 대답으로 표시하는 것이 옳지 않을 것입니다. 그렇습니까? – Honnes

+0

나는 도움을 요청하는 것이 아니라 단지 도우려는 것입니다. – jonnii

관련 문제