Nhibernate Session.Get と Session.CreateCriteria の違いは何ですか?
私の話は:
私たちの製品では、インターフェイス ISoftDeletable を追加することで softDeletion を実装しました。このインターフェイスを実装する各クラスには、deletedDate および deletedBy フィールドがあります。また、AuditableEntity クラスがあります。つまり、それを実装する各クラスには、createdDate、createdBy、modifiedDate、modifiedBy があります。
ソースは次のとおりです。
public class SaveUpdateEventListener : DefaultSaveEventListener
{
private readonly ISecurityContextService securityContextService;
public SaveUpdateEventListener(ISecurityContextService securityContextService)
{
this.securityContextService = securityContextService;
}
protected override object PerformSaveOrUpdate(SaveOrUpdateEvent @event)
{
this.PrepareAuditableEntity(@event);
return base.PerformSaveOrUpdate(@event);
}
private void PrepareAuditableEntity(SaveOrUpdateEvent @event)
{
var entity = @event.Entity as AuditableEntity;
if (entity == null)
{
return;
}
if (this.securityContextService.EdiPrincipal == null)
{
throw new Exception("No logged user.");
}
if (entity.Id == 0)
{
this.ProcessEntityForInsert(entity);
}
else
{
this.ProcessEntityForUpdate(entity);
}
}
private void ProcessEntityForUpdate(AuditableEntity entity)
{
entity.ModifiedBy = securityContextService.GetLoggedUser();
entity.ModifiedDate = DateTime.Now;
}
private void ProcessEntityForInsert(AuditableEntity entity)
{
entity.CreatedBy = securityContextService.GetLoggedUser();
entity.CreatedDate = DateTime.Now;
}
また、Session.Get メソッドをオーバーライドしました。
public virtual T Get(long id)
{
if (typeof(ISoftDeletable).IsAssignableFrom(typeof(T)))
{
return
this.Session.CreateCriteria(typeof(T))
.Add(Restrictions.Eq("Id", id))
//.Add(Restrictions.IsNull("DeletedDate"))
.UniqueResult<T>();
}
return Session.Get<T>(id);
}
あるコンテキストで、アプリケーションは、softDeletable および監査可能なエンティティの Get メソッドで StackOverflow 例外をスローしました。調査の結果、PrepareEntityForUpdate/securityContextService.GetLoggedUser とカスタム リポジトリの Get メソッドの間にループが作成されることがわかりました。ご覧のとおり、DeletedDate への制限についてコメントしました。これは、Session.Get(id) が作成された基準と同じ結果を返す必要があることを意味します。しかし、 this.Session.CreateCriteria(typeof(T)) を通過すると、StackOverflow 例外が発生します。これをコメントして return Session.Get(id) (deletiondate を考慮せずに) のみを残すと、すべて正常に動作します。
これにより、Session.Get と Session.CreateCriteria の動作が異なるように思えます。何か案は?