Différence betwwen Nhibernate Session.get et session.createCriteria
-
21-09-2019 - |
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?
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.