Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference betwwen Nhibernate Session.Get and Session.CreateCriteria

What is the difference between Nhibernate Session.Get and Session.CreateCriteria?

My story is:

In our product we implemented a softDeletion by adding a Interface ISoftDeletable, each class which implement this Interface has deletedDate and deletedBy field. Also we have AuditableEntity class which means that each class which implement it has: createdDate, createdBy, modifiedDate, modifiedBy.

here are the sources:

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;
    }

Also we have overrided the Session.Get method.

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);
    }

Now in some context the application thrown an StackOverflow exception in the Get methods on a softDeletable and auditable entity. After some investigation I noted that it creates a loop between PrepareEntityForUpdate/securityContextService.GetLoggedUser and Get method from our custom Repository. As you can see I've commented the restriction to DeletedDate, this means that Session.Get(id) should return same result as created criteria. But if I go though this.Session.CreateCriteria(typeof(T)) I get the StackOverflow exception, if I comment this one and leave only return Session.Get(id) (without taking in consideration deletiondate) all works fine.

This makes me to think that Session.Get and Session.CreateCriteria works differently. Any ideas?

like image 232
isuruceanu Avatar asked Dec 07 '25 10:12

isuruceanu


2 Answers

Get will use the Session cache. Criteria will not.

In other words: Criteria will always result in a SQL query / call to the DB. Get will not always result in a sql query. If an entity has already been loaded by NHibernate in a session, and you want to retrieve the entity again using Get, NHibernate will return the entity that it has already loaded from its cache.

like image 176
Frederik Gheysels Avatar answered Dec 12 '25 02:12

Frederik Gheysels


In addition to this you can set where parameter at mapping class. There you can add: "DeletedDate IS NULL". When Get is executed NHibernate add this WHERE statement to generated query.

like image 20
dariol Avatar answered Dec 12 '25 03:12

dariol



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!