2008-10-21 35 views
23

Supongamos que los objetos del tipo A se almacenan en DB. Esta es la forma en que se carga uno específico de la base de datos utilizando hibernación:Hibernar: compruebe si existe el objeto

org.hibernate.Session session = ...; 
long id = 1; 
A obj = session.load(A.class, id); 

Si no existe objeto con id = 1 voy a tener ObjectNotFoundException. ¿Pero hay una manera de verificar si tal objeto existe sin tener que atrapar la excepción? Lo que me gustaría es tener algo bajo como:

org.hibernate.Session session = ...; 
long id = 1; 
boolean exists = session.exists(A.class, id); 
if(exists){ 
// do smth..... 
} 

No se pudo encontrar que hibernate docs ...

Respuesta

24

Puede utilizar session.get:

public Object get(Class clazz, 
        Serializable id) 
      throws HibernateException 

Se devolverá un valor nulo si el objeto no existe en la base de datos. Puede encontrar más información en Hibernate API Documentation.

+0

Hmm ... sigo teniendo el mismo (ObjectNotFoundException) no importa si me usa "cargar" o "obtener". –

+0

Quizás esté obteniendo una excepción de una session.load() anterior? De los documentos para ObjectNotFoundException: "Esta excepción no se inicia cuando se llama a load() porque load() devuelve un proxy si es posible. Use Session.get() para comprobar si existe una fila en el db." – Juanma

+2

funciona pero es un enfoque lento ya que Hibernate tendrá que buscar todas las columnas y afectarlas al nuevo objeto y almacenarlo en la sesión. Si no quiere desperdiciar recursos inútilmente, considere el enfoque HQL en su lugar. –

42

puede utilizar HQL para comprobar la existencia de objetos:

public Boolean exists (DTOAny instance) { 
    Query query = getSession().    
    createQuery("select 1 from DTOAny t where t.key = :key"); 
     query.setString("key", instance.getKey()); 
    return (query.uniqueResult() != null); 
} 

hibernauniqueResult() método devuelve null si no se encontró ningún dato. Al usar HQL puede crear criterios de consulta más complejos.

10

Hibernate

Obtiene única clave para un rendimiento óptimo:

public boolean exists(Class clazz, String idKey, Object idValue) { 
    return getSession().createCriteria(clazz) 
      .add(Restrictions.eq(idKey, idValue)) 
      .setProjection(Projections.property(idKey)) 
      .uniqueResult() != null; 
} 

APP

Desde Hibernate es una implementación de la APP, es posible inject un EntityManager. Este método también tiene un buen rendimiento, ya que lazily fetches la instancia:

método
public boolean exists(Class clazz, Object key) { 
    try { 
     return entitymanager.getReference(Entity.class, key) != null; 
    } catch (EntityNotFoundException.class) { 
     return false; 
    } 
} 
+2

No necesita un condicional para la última línea: puede usar .uniqueResult()! = Null; – stephenwebber

+1

¡Gracias por la pista, actualicé el código! – Journeycorner

3

Un poco simplificada de @Journeycorner

public boolean exists(Class<?> clazz, Object idValue) { 
    return getSession().createCriteria(clazz) 
      .add(Restrictions.idEq(idValue)) 
      .setProjection(Projections.id()) 
      .uniqueResult() != null; 
} 

A siguiente método puede ser útil también. Tenga en cuenta, que este método sólo se puede utilizar con los criterios que pueden producir no más de un registro (como Restrictions.idEq() criterios)

public static boolean uniqueExists(Criteria uniqueCriteria) { 
    uniqueCriteria.setProjection(Projections.id()); 
    return uniqueCriteria.uniqueResult() != null; 
}