2011-09-19 16 views
6

Deseo poder verificar si una sesión contiene una entidad de una clase/identificador determinada. No puedo ver una manera de hacer esto en este momento.Hibernate session.contains (Class clazz, Serializable id)

  • toma un objeto entidad no clase + tecla de
  • get() consultas de la base de datos si la entidad no está presente, que no quiero hacer
  • load() nunca se devuelve un valor nulo como un proxy se crea siempre por lo No puedo usar este método

¿Es posible hacer lo anterior sin efectos secundarios/consultas a DB?

+0

Sólo por curiosidad - ¿por qué necesita saber si el objeto con el identificador dado es en la sesión? ¿No puedes simplemente hacer 'get (id)' y confiar en el hecho de que si el objeto ya está en Session, Hibernate devolverá esa instancia y no volverá a consultarla? –

+0

En este caso, estoy intentando que hibernate interactúe con algunas memorias caché personalizadas, pero solo en instancias muy específicas, la mayoría de las veces estoy contento por el comportamiento predeterminado de presionar la base de datos, así que quiero verificar la sesión para ver si hay un objeto presente. , si no lo carga desde el caché. La clave es que no puedo molestar nada en la sesión ya que puede haber referencias a ella desde otros objetos con referencias de varios a uno. –

+0

@MikeQ Tenías toda la razón sobre la forma en que funciona IdentityMap, por lo que mi respuesta ahora está eliminada. – Marcelo

Respuesta

1

Respondiendo a mi propia pregunta.

No creo que esto sea posible con las API públicas. Sin embargo, si usted está dispuesto a tolerar un poco de queso se puede hacer lo siguiente

 SessionImplementor sessionImplementor = ((SessionImplementor)session); 
     EntityPersister entityPersister = sessionImplementor.getFactory().getEntityPersister(clazz.getName()); 
     PersistenceContext persistenceContext = sessionImplementor.getPersistenceContext(); 

     EntityKey entityKey = new EntityKey(id, entityPersister, EntityMode.POJO); 

     Object entity = persistenceContext.getEntity(entityKey); 

     if (entity != null) 
      return entity; 

     entity = persistenceContext.getProxy(entityKey); 

     if (entity != null) 
      return entity; 

     return null; 

Esto se basa en las API internas de hibernación lo que no puede trabajar en el futuro si se cambia interiormente.

1

No es que yo sepa. La sesión siempre verificará la base de datos si intenta obtener una entidad de un tipo y una identificación en particular y no la contiene.

De hecho, esa es una de las cosas buenas del modelo. No tiene que importar de dónde obtiene JPA/Hibernate el objeto, el caché (1er o 2do nivel) o el DB.

Si tiene una entidad en la memoria, puede verificar si está desvinculada de la sesión, pero no si está en la sesión.

0

Utilice getIdentifier(..). Devuelve el valor del identificador de la entidad dada como asociado con la sesión actual, vea Javadoc.

+0

Eso no es lo que estoy pidiendo. –

3

Esto funciona:

public boolean isIdLoaded(Serializable id) 
{ 
    for (Object key : getSession().getStatistics().getEntityKeys()) 
    { 
     if (((EntityKey) key).getIdentifier().equals(id)) 
     { 
      return true; 
     } 
    } 

    return false; 
} 
Cuestiones relacionadas