Question

Quelle est la différence entre Nhibernate Session.get et session.createCriteria?

Mon histoire est:

Dans notre produit, nous mis en place un softDeletion en ajoutant une interface ISoftDeletable, chaque classe qui mettent en œuvre cette interface a deletedDate champ et deletedBy. Nous avons aussi classe AuditableEntity ce qui signifie que chaque classe qui mettent en œuvre qu'il a. CreatedDate, CreatedBy, ModifiedDate, ModifiedBy

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

Nous avons aussi overrided la méthode 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);
    }

Maintenant dans un certain contexte l'application jeté une exception StackOverflow dans les méthodes Get sur une softDeletable et entité auditable. Après enquête, je remarquai qu'il crée une boucle entre PrepareEntityForUpdate / securityContextService.GetLoggedUser et obtenir la méthode de notre référentiel personnalisé. Comme vous pouvez le voir, je l'ai commenté la restriction à DeletedDate, cela signifie que Session.get (id) doit retourner même résultat que les critères créés. Mais si je vais bien this.Session.CreateCriteria (typeof (T)) Je reçois l'exception StackOverflow, si je commente celui-ci et laisse revenir seulement Session.get (id) (sans prendre en considération deletiondate) tout fonctionne très bien.

Cela me fait de penser que fonctionne Session.get et session.createCriteria différemment. Des idées?

Était-ce utile?

La solution

Get utilisera le cache de session. Les critères ne seront pas.

En d'autres termes: critères entraînera toujours une requête SQL / appel à la DB. Obtenez entraînera pas toujours dans une requête SQL. Si une entité a déjà été chargé par NHibernate dans une session, et que vous voulez récupérer l'entité en utilisant à nouveau Get, NHibernate retournera l'entité qu'il a déjà chargé de son cache.

Autres conseils

En plus de cela, vous pouvez définir où le paramètre à la classe de cartographie. Vous pouvez y ajouter: "DeletedDate IS NULL". Lorsque Get est exécuté NHibernate ajouter cette instruction WHERE à la requête générée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top