2009-08-13 5 views
1

NHibernate의 최신 빌드에 이벤트 리스너를 구현하여 편집자와 편집 내용을 추적하기로 결정했습니다. 내 질문은 이것입니다 - 아래에 작동하고 그것을 통해 단계를 수행 할 수 있지만 이러한 변경 사항을 저장하는 방법을 잘 모르겠습니다 ... 감사 테이블을 작성하고 저장 또는 호출 할 매핑을 작성해야합니까? 메서드는 "updated by"및 "updated date"정보와 함께 객체의 상태를 얻는 것이 가장 좋습니다. 그래서 나중에이 객체를 가져올 수 있습니다.NHibernate 이벤트 리스너 지속성 - 어떻게 작동합니까?

기본 클래스가이 기능 (또는이 기능의 하위 집합)을 제공한다고 생각했지만 여기에 누락 된 부분에 대한 좋은 블로그 게시물을 찾을 수없는 것 같습니다. 어떤 도움을 많이 주시면 감사하겠습니다!

Imports NHibernate.Event 
Imports NHibernate.Event.Default 

Public Class CustomSaveEventListener 
    Inherits DefaultSaveEventListener 

    Protected Overloads Overrides Function PerformSaveOrUpdate(ByVal evt As SaveOrUpdateEvent) As Object 
     Dim entity As IEntity = TryCast(evt.Entity, IEntity) 
     If entity IsNot Nothing Then 
      ProcessEntityBeforeInsert(entity) 
     End If 

     Return MyBase.PerformSaveOrUpdate(evt) 
    End Function 

    Friend Overridable Sub ProcessEntityBeforeInsert(ByVal entity As IEntity) 
     Dim user As User = DirectCast(Thread.CurrentPrincipal, User) 
     entity.ModifiedBy = user.UserName 
     entity.ModifiedDate = DateTime.Now 
    End Sub 
End Class 

리플렉터를 열면이 기본 클래스 방법에 대해 아래를 참조하십시오.하지만 정확히 무엇을하고 있습니까?

protected override object PerformSaveOrUpdate(SaveOrUpdateEvent @event) 
{ 
    EntityEntry entry = @event.Session.PersistenceContext.GetEntry(@event.Entity); 
    if ((entry != null) && (entry.Status != Status.Deleted)) 
    { 
     return this.EntityIsPersistent(@event); 
    } 
    return this.EntityIsTransient(@event); 
} 

답변

3

엔티티가 유지 (저장 또는로드) 될 때 NH는 내부 사전 (session.PersistenceContext)에이를 추가합니다. 이 사전의 핵심은 엔티티 상태 (그리고 내가 생각하기에 몇 가지 다른 것들)에 대한 정보를 담고있는 EntityEntry이다. 엔티티가 저장되지 않으면 (일시적) 내부 사전에서 EntityKey를 찾지 않습니다.

이 함수를 읽으면이 함수는 엔티티가 일시적인지 아닌지를 확인하고 좋은 함수를 호출합니다 (EntityIsTransient 트리거가 동작을 저장하고 EntityIsPersitent가 업데이트 동작을 트리거한다고 생각합니다).

EntityEntry entry = @event.Session.PersistenceContext.GetEntry(@event.Entity); 
    if ((entry != null) && (entry.Status != Status.Deleted)) 
    { 
     return this.EntityIsPersistent(@event); 
    } 
    return this.EntityIsTransient(@event); 

하지만 문제는 로그 시스템처럼 보입니다. ISaveOrUpdateEvent를 구현하고 log4net을 사용하여 편집 내용을 기록하면 어떨까요?

+0

Session.PersistenceContext에 대한 세부 정보 주셔서 감사합니다 - 실제로 로깅에 대해 시스템의 "내역"동작을 유지하려하지만 저장 프로 시저를 사용하여 저장시 기록을 삽입하는 대신 NHibernate 나를 위해 이것을 할. SQL 서버에서 히스토리 테이블에 대한 매핑 파일을 만들고이 클래스에서 업데이트를 호출하기 위해 이와 같은 것을 유지하는 유일한 방법입니까? (저장 또는 업데이트 이벤트 직후) –

+0

여러분을 환영합니다. 두 번째 질문에 세부 사항으로 대답 할 수 없습니다. 나는 너의 생각에 대해 기분이 좋지 않다. NH가 저장 또는 업데이트 이벤트를 가로 챌 때 NH는 이미 데이터베이스 액세스 및 일괄 처리 프로세스에 있습니다. 나는 NH가 행동을 수정하지 않으려 고 노력 일단 플러싱, 두려움 무언가에 의해. 내가 볼 수있는 NH 전용 솔루션은 모든 변경 사항을 스택에 넣고 세션이 플러시 된 후 로그 클래스의 저장을 다시 실행하거나 프로그램 실행이 끝날 때 수행하는 것입니다. – Nelson

+0

nh 세션 (연결 손실과 같은)에서 예외가 발생하면 상황이 더욱 복잡해집니다. 그것이 내가 log4net (http://logging.apache.org/log4net/index.html)에 관해 이야기 한 이유입니다. 데이터베이스 나 다른 것에 로그를 기록하도록 지정할 수 있습니다 (appender를 찾으십시오). log4net 설정은 처음에는 이해하기가 약간 어렵지만 필요한 도구가있을 것입니다. – Nelson

관련 문제