NHibernate.Envers
코드를 살펴본 후에 잘못된 인터페이스를 구현하고 있음을 깨달았습니다. 이제는 어떤 인터페이스를 사용하여 조금 더 잘 작동하는지 알았습니다.`PreCollectionUpdateEvent`가 수정 된 컬렉션을 삽입하지 않는 이유는 무엇입니까?
내 현재의 구현은 다음과 같습니다 : 디버깅을 통해
public class PreCollectionUpdate : IPreCollectionUpdateEventListener
{
public void OnPreUpdateCollection(PreCollectionUpdateEvent @event)
{
var collectionEntry = @event.Session.PersistenceContext.GetCollectionEntry(@event.Collection);
if(!collectionEntry.LoadedPersister.IsInverse)
return;
var collection = @event.Collection;
var collectionEntries = collection.Entries(collectionEntry.LoadedPersister);
foreach(var entry in collectionEntries)
{
if(!(entry is TrackableEntity))
return;
var trackableEntity = entry as TrackableEntity;
trackableEntity.AddedAt = Time.Now;
trackableEntity.AddedBy = User.Current;
}
}
}
나는 그것이 내 컬렉션을 수정 제대로 불러되고 볼 수 있습니다. 그러나 어떤 이유로 먼저 AddedAt
및 AddedBy
에 대한 기본값으로 내 컬렉션에 항목을 삽입 한 다음 해당 값을 채우기 위해 나중에 업데이트를 수행합니다.
using (var transaction = Session.BeginTransaction())
{
var locate = new Locate
{
TicketNumber = 123456789,
Status = Status.InProgress
};
Session.Save(locate);
transaction.Commit();
}
using (var transaction = Session.BeginTransaction())
{
var locate1 = Session.Get<Locate>(1);
locate1.AddReview(new AllClear());
Session.Save(locate1);
transaction.Commit();
}
using (var transaction = Session.BeginTransaction())
{
var locate1 = Session.Load<Locate>(1);
transaction.Commit();
}
이유입니다 : 여기
내 테스트 코드인가?내 테스트 디버깅 내 거래를 완료 한 후 AddedBy
및 AddedWhen
속성이 모두 올바르게 채워지는 것을 확인할 수 있습니다. 왜 수정 된 컬렉션을 커밋하지 않는지 확실하지 않습니다.
내 코드 전체에 Console.Write
문장을 추가하면 이후에 내 이벤트 수신기가 으로 호출됨을 알 수 있습니다. 내 세션을 커밋합니다.
NHibernate: INSERT INTO Locates (AddedAt, AddedBy, TicketNumber, Status, SomeOtherField) VALUES (@p0, @p1, @p2, @p3, @p4); select last_insert_rowid();@p0 = 1/1/0001 00:00:00 [Type: DateTime (0)], @p1 = NULL [Type: String (0)], @p2 = 123456789 [Type: Int64 (0)], @p3 = 'InProgress' [Type: String (0)], @p4 = NULL [Type: String (0)]
Saving review...
Commiting...
NHibernate: INSERT INTO "Review" (AddedAt, AddedBy, Locate_id) VALUES (@p0, @p1, @p2); select last_insert_rowid();@p0 = 1/1/0001 00:00:00 [Type: DateTime (0)], @p1 = NULL [Type: String (0)], @p2 = NULL [Type: Int32 (0)]
In event listener...
Completed filling auditable properties.
또한 IFlushEntityEventListener
에서 inheritign 시도했지만 같은 문제가 발생합니다. AddedAt
및 AddedBy
속성이 데이터베이스에 유지되지 않고 커밋됩니다. 내 객체는 다음 번에 변경 될 것이므로 객체와 함께 NHibernate가 더티라는 것을 알게되고 데이터베이스에 업데이트 명령을 내린다. 내가 원하는 것은 AddedAt
과 AddedBy
속성이 초기 커밋에서 커밋되는 것입니다.
제가 명확하지 않은 경우 알려주십시오.
이 접근법에 대해 싫어했던 점은'AddedBy'와'AddedAt'에 nullables를 허용해야한다는 것입니다. (OnSaveOrUpdate'는 null 또는 일시적인 값을 저장하려고하면 Hibernate가 예외를 던지는 곳입니다.) 실행됩니다. 'OnPreInsert' 전에. – Nosila
@ 노질라, 좋은 지적이지만, 저장을 위해 생성자에서 TrackableEntity의 필드를 초기화하고 (이미 저장 한 값을 가질 수있는 업데이트에 대해) 몇 가지 방법으로는 해결할 수 없었습니다. 후크가 실행될 때까지 잘못된 값). 나는 그 더러운 것을 안다. 현재 프로젝트에서 실제로하고있는 다른 옵션은 IInterceptor를 사용하고 실제로 트랜잭션 수준에서 감사 로그를 만드는 것입니다. 이것은 어쨌든 사용자에게 더 유용합니다. 그런 다음 전체 트랜잭션을 일종의 감사 로그에 저장할 수 있습니다. – acarasso
@acarasso : 생각해 본 기사입니다. http://ayende.com/blog/3987/nhibernate-ipreupdateeventlistener-ipreinserteventlistener – DanP