2010-03-13 6 views
0

을 변화를 감지하고 사용하지 않습니다. 그러나, 나는이 작업을 수행 할 때문제는 내가이 할 때 NHibernate에 이전 값

Cat x = new Cat(); 
Session.Save(x); 
x.Name = "fritz"; 
Session.Flush(); 

그게 내가 Session.Save()를 호출 할 때이 무엇 때문에 내가 이름에 대한 NULL 얻을. 왜 NHibernate는 변경을 감지하지 못한다 - 또는 더 나은 아직, Flush() 시간에 INSERT 문에 대한 값을 취하는가?

추가 :Session.FlushModeNone으로 설정되어 있으므로 그렇게 말할 때까지 자동으로 플래시되지 않습니다. GUID primary 키 (guid.comb 생성기 사용)도 사용하고 있습니다.

내가 이것을하는 이유는 세션을 "더티 (dirtiness)"추적기로 사용하기 때문입니다. 저는 Windows Forms 응용 프로그램을 작성하고 있으며 모든 양식은 양식이있는 한 지속되는 별도의 세션을 가지고 있습니다. 세션은 가능한 한 많이 연결이 끊어 지므로 ADO.NET 연결이 끊어지지 않습니다 (MDI 응용 프로그램이고 열 수있는 양식의 수 제한이 없습니다). 모든 양식에는 "OK"버튼과 "Cancel"버튼이 있습니다. "OK"버튼은 Session.Flush()을 호출 한 다음 양식을 닫습니다. "취소"버튼은 양식을 닫고 사용자가 변경 한 내용을 모두 무시합니다.

글쎄, 적어도 내가 원한다. 위의 버그로 인해 문제가 발생했습니다.

답변

0

매우 좋은 이유가 있지 않는 한, 설명 플러시 호출 대신 트랜잭션을 사용해야합니다. 실제 응용 프로그램에서

using (var session = createSession()) 
{ 
    using (var transaction = session.BeginTransaction()) 
    { 
     Cat x = new Cat(); 
     session.Save(x); 
     x.Name = "fritz"; 
     try 
     { 
      transaction.Commit(); 
     } 
     catch 
     { 
      // prevents your database from getting corrupt when you have a bug 
      transaction.RollBack(); 
      throw; 
     } 
    } 
} 

, 각 데이터 -에 호출 할 필요가 없도록, 커밋 및 응용 프로그램에서 별도의 부분에 백 롤, 트랜잭션 생성을 숨길 수있는 좋은 방법입니다 액세스 블록. 관계 데이터베이스가있는 대부분의 응용 프로그램에서 한 트랜잭션은 사용자에 대해 한 화면을 처리하는 전체 코드로 래핑됩니다. 이로 인해 사용자가 만든 모든 동작이 성공하거나 버그가있는 경우 원자 블록으로 실패합니다. 화면에서 사용자가 변경 한 모든 데이터는 저장되거나 아무것도 저장되지 않으며 일부만 저장됩니다.

+0

사실,하지만 조금 다른 방식으로 NHibernate를 사용하려고합니다. Windows 응용 프로그램을 만들고 있고 변경 추적을 위해 세션을 사용하고 있습니다. 즉, 양식을 열면 세션이 시작됩니다. 데이터를 검색해야하는 경우를 제외하고는 연결이 끊어져 있습니다. 양식에 "OK"버튼과 "Cancel"버튼이 있습니다. "OK"를 클릭하면,'Flush()'를 호출합니다. "취소"를 클릭하면 세션이 자동으로 삭제되고 모든 변경 사항이 손실됩니다. 이 문제를 제외하고는 ... –

+0

자연히, 나는 또한 세션의'FlushMode'를'Never'로 설정하여 사용자가 "OK"를 클릭하기 전에 뜻하지 않은 커밋이 일어나지 않도록합니다. –

+1

프리젠 테이션 모델!= 도메인 모델 – Paco

0

NHibernate는 변경 사항을 추적하지만, 작성한 코드는 Save를 호출 한 시점의 값과 Save를 호출 한 후의 변경 사항에 대한 업데이트가 삽입되도록합니다. Save는 객체를 영속화시키고 (삽입), Hibernate는 영속 객체 (변경)에 대한 변경을 추적하기 시작합니다. 세션이 플러시 될 때 삽입 및 업데이트가 커밋됩니다.

우리는 Windows Forms 응용 프로그램과 비슷한 문제에 직면하고 있으며 다른 접근 방법을 취할 것입니다. FlushMode는 Auto (기본값)로 유지되고 사용자가 작업을 취소하면 세션에서 개체가 제거됩니다 (ISession.Evict). 객체를 제거하면 과도하게되어 원하는 동작이됩니다.

+0

잠깐, 그게 당신이 DB에 개체를 삽입하고, 나중에 사용자가 취소하면 그것을 삭제 의미합니까? –

+0

안 돼요. 즉, 사용자가 작업을 취소하여 세션이 플러시 된 경우 변경 내용이 유지되지 않으면 개체가 세션에서 제거됩니다. 일반적으로 세션 종료를 표시합니다. 필요한 경우 오브젝트가 다시 검색되어 이전 상태로 표시됩니다. –

+0

오, 오케이. 하지만 NHibernate가 세션을 플러시하기로 결정한 다음 사용자가 취소하면 어떻게됩니까? 실제로 세션의 수명은 언제입니까? 그리고 - 당신도 MDI 응용 프로그램을 가지고 있습니까? –