2011-08-03 12 views
6

No puedo entender la diferencia entre load y get. el siguiente fragmento de código no funciona cuando doy session.load. Da una excepción de puntero nulo. Pero lo mismo funciona cuando estoy usando session.get().entendiendo session.get vs session.load método en hibernación

public Employee getEmployee(final String id){   
     HibernateCallback callback = new HibernateCallback() { 
      public Object doInHibernate(Session session) 
       throws HibernateException,SQLException { 
       //return (Employee)session.load(Employee.class, id); doesn't work 
        return (Employee)session.get(Employee.class, id); //it works 
      } 
     };   
     return (Employee)hibernateTemplate.execute(callback); 
    } 

También quiero entender como objeto Session se pasa a doInHibernate.?
¿cuándo comienza la sesión y cuándo termina?

Seguimiento de la pila es el siguiente

Exception in thread "main" java.lang.NullPointerException 
    at org.hibernate.tuple.AbstractEntityTuplizer.createProxy(AbstractEntityTuplizer.java:372) 
    at org.hibernate.persister.entity.AbstractEntityPersister.createProxy(AbstractEntityPersister.java:3121) 
    at org.hibernate.event.def.DefaultLoadEventListener.createProxyIfNecessary(DefaultLoadEventListener.java:232) 
    at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:173) 
    at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:87) 
    at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:862) 
    at org.hibernate.impl.SessionImpl.load(SessionImpl.java:781) 
    at org.hibernate.impl.SessionImpl.load(SessionImpl.java:774) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.springframework.orm.hibernate3.HibernateTemplate$CloseSuppressingInvocationHandler.invoke(HibernateTemplate.java:1282) 
    at $Proxy0.load(Unknown Source) 
    at hibernate.EmployeeDao$1.doInHibernate(EmployeeDao.java:25) 
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406) 
    at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:339) 
    at hibernate.EmployeeDao.getEmployee(EmployeeDao.java:29) 
    at hibernate.SpringHibernateTest.main(SpringHibernateTest.java:26) 
+0

¿Qué quiere decir con "no funciona"? ¿Cuál es la línea que causa una NullPointerException? –

+1

Google for "at org.hibernate.tuple.AbstractEntityTuplizer.createProxy (AbstractEntityTuplizer.java:372)". Está ejecutando una versión anterior de Hibernate, y encontré varios motivos posibles para esta excepción (mala asignación, errores, etc.). No tiene mucho que ver con load vs get. –

+0

@JB Nizet: ¡Muchas gracias! Comprobaré la configuración de mi compilación y actualizaré los viejos frascos. Muchas veces me he enfrentado a este problema y estoy aprendiendo a mavenizar los proyectos ... pero, ¿pueden ayudarme con otras dudas? ** cómo se pasa el objeto Session a doInHibernate.? ¿cuándo comienza la sesión y cuándo termina? ** –

Respuesta

8
I am not able to understand the difference between load and get 

La diferencia principal es: si la carga() no puede encontrar el objeto en la caché o base de datos, se produce una excepción. El método load() nunca devuelve null. El método get() devuelve null si no se puede encontrar el objeto. Otra diferencia es que el método load() puede devolver un proxy en lugar de una instancia real, pero get() nunca devuelve el proxy.

the following piece of code doesn't work when i give session.load. It gives null pointer exception. But same does work when i am using session.get() . 

Si no se encuentra objeto, método de carga tirará excepción sino conseguir won't.Simple

Editar: Elaborar las cosas,

  1. Cuando get() se llama al método, golpeará directamente la base de datos, buscará el resultado y lo devolverá. Si no se encuentran campos coincidentes, gustosamente devolverá nulo.

  2. Pero cuando se ejecuta load(), primero buscará en el caché el objeto requerido. Si se encuentra, todo está bien. Pero si el objeto no se encuentra en la memoria caché, el método load() devolverá un proxy. Puede considerar este proxy como un acceso directo para la ejecución de consultas de bases de datos. Recuerde, aún no se ha realizado ningún hit en la base de datos. Ahora cuando realmente acceda al objeto, se rastreará el proxy y se realizará el acierto de la base de datos.

Veamos un ejemplo simple.

User user=(User)session.load(User.class, new Long(1));//Line 1 
System.out.println(user.getPassword());//Line 2 

Si el objeto de usuario con la clave principal 1 no está disponible en la sesión, el método de carga() se establece un proxy para la base de datos en la línea 1. Ahora cuando el valor real del objeto 'usuario' se llama, es decir, línea 2, se rastreará el proxy y se golpeará la base de datos.

Espero que esto ayude.

+1

No: load no busca el objeto en la base de datos. Devuelve el objeto que tiene en su caché de sesión, o crea un proxy, suponiendo que el objeto existe en la base de datos. –

+0

@Pravin: Ya leí esto en el manual. Quería que alguien me explicara el significado de lo que acaba de decir. Cuando se dice que el método de carga devuelve el proxy en lugar de la instancia real, entiendo que devuelve los datos de algún caché y por lo tanto, el método de carga no requiere múltiples accesos de datos a la base de datos. También entiendo que la excepción del puntero nulo se produce cuando se hace referencia a un valor nulo, mi pregunta era por qué era nula y cómo puedo hacer que funcione con carga para que tu respuesta nada útil. –

+0

@Anupam, he editado la publicación para aclarar las cosas. Espero que esto recupere el representante que había perdido. –