lazy - Hibernate: Diferencia entre session.get y session.load
jpa initialize lazy object (8)
Desde la API, pude ver que tiene algo que ver con el proxy. Pero no pude encontrar mucha información sobre el proxy y no entiendo la diferencia entre llamar a session.get
y session.load
. ¿Podría alguien explicarme o dirigirme a una página de referencia?
¡¡Gracias!!
Bueno, en nhibernate al menos, session.Get (id) cargará el objeto de la base de datos, mientras que session.Load (id) solo creará un objeto proxy sin salir de su servidor. Funciona igual que cualquier otra propiedad de carga lenta en sus POCO (o POJOs :). A continuación, puede usar este proxy como una referencia al objeto en sí para crear relaciones, etc.
Piense que es como tener un objeto que solo mantiene el Id y que cargará el resto si alguna vez lo necesita. Si solo lo está pasando para crear relaciones (como FK), la identificación es todo lo que necesitará.
Desde el foro de Hibernate :
Esto del libro Hibernate in Action. Bueno, lee esto ...
Recuperar objetos por identificador El siguiente fragmento de código de Hibernate recupera un objeto Usuario de la base de datos:
User user = (User) session.get(User.class, userID);
El método get () es especial porque el identificador identifica de manera única una sola instancia de una clase. Por lo tanto, es común que las aplicaciones usen el identificador como un identificador conveniente para un objeto persistente. La recuperación por identificador puede usar la memoria caché al recuperar un objeto, evitando que se golpee la base de datos si el objeto ya está en la memoria caché. Hibernate también proporciona un método load ():
User user = (User) session.load(User.class, userID);
El método load () es más antiguo; get () se agregó a la API de Hibernate debido a la solicitud del usuario. La diferencia es trivial:
Si load () no puede encontrar el objeto en el caché o la base de datos, se lanza una excepción. El método load () nunca devuelve null. El método get () devuelve null si no se puede encontrar el objeto.
El método load () puede devolver un proxy en lugar de una instancia real persistente. Un proxy es un marcador de posición que activa la carga del objeto real cuando se accede por primera vez; Por otro lado, get () nunca devuelve un proxy. Elegir entre get () y load () es fácil: si está seguro de que el objeto persistente existe, y la inexistencia se considerará excepcional, load () es una buena opción. Si no está seguro de que haya una instancia persistente con el identificador dado, use get () y pruebe el valor de retorno para ver si es nulo. Usar load () tiene una implicación adicional: la aplicación puede recuperar una referencia válida (un proxy) a una instancia persistente sin golpear la base de datos para recuperar su estado persistente. Entonces, load () podría no arrojar una excepción cuando no encuentre el objeto persistente en el caché o la base de datos; la excepción se lanzaría más tarde, cuando se accede al proxy. Por supuesto, recuperar un objeto por identificador no es tan flexible como usar consultas arbitrarias.
También debemos tener cuidado al usar load ya que arrojará una excepción si el objeto no está presente. Tenemos que usarlo solo cuando estemos seguros de que ese objeto existe.
Un punto extra más ::
get method of Hibernate La clase Session devuelve null si el objeto no se encuentra en el caché ni en la base de datos. mientras que el método load () arroja ObjectNotFoundException si el objeto no se encuentra en el caché ni en la base de datos, pero nunca devuelve un valor nulo.
Una consecuencia indirecta del uso de "carga" en lugar de "obtener" es que el bloqueo optimista con un atributo de versión puede no funcionar como cabría esperar. Si una carga simplemente crea un proxy y no lee de la base de datos, la propiedad de la versión no se carga. La versión solo se cargará cuando / luego se refiera a una propiedad en el objeto, lo que activará una selección. Mientras tanto, otra sesión puede actualizar el objeto, y su sesión no tendrá la versión original que necesita para realizar la verificación de bloqueo optimista, por lo que la actualización de la sesión sobrescribirá la actualización de la otra sesión sin previo aviso.
Aquí hay un intento de esbozar este escenario con dos sesiones trabajando con un objeto con el mismo identificador. La versión inicial para el objeto en DB es 10.
Session 1 Session 2
--------- ---------
Load object
Wait a while..
Load object
Modify object property
[triggers db ''select'' -
version read as 10]
Commit
[triggers db update,
version modified to 11]
Modify object property
[triggers db ''select'' -
version read as 11]
Commit
[triggers db update,
version modified to 12]
De hecho, queremos que la sesión 1 se comprometa a fallar con una excepción de bloqueo optimista, pero tendrá éxito aquí.
El uso de "get" en lugar de "load" soluciona el problema, porque get emitirá inmediatamente una selección, y los números de versión se cargarán en los momentos correctos para la comprobación de bloqueo optimista.
Una excelente explicación se encuentra en http://www.mkyong.com/hibernate/different-between-session-get-and-session-load
session.load ():
Siempre devolverá un "proxy" (término de Hibernate) sin tocar la base de datos.
En Hibernate, proxy es un objeto con el valor del identificador dado, sus propiedades aún no se han inicializado, simplemente se ve como un objeto falso temporal.
Siempre devolverá un objeto proxy con el valor de identidad dado, incluso el valor de identidad no existe en la base de datos. Sin embargo, cuando intente inicializar un proxy recuperando sus propiedades de la base de datos, golpeará la base de datos con una instrucción select. Si no se encuentra una fila, se lanzará una ObjectNotFoundException.
session.get ():
Siempre golpea la base de datos (si no se encuentra en la caché) y devuelve el objeto real, un objeto que representa la fila de la base de datos, no el proxy.
Si no se encuentra una fila, devuelve nulo.
load () no puede encontrar el objeto desde el caché o la base de datos, se lanza una excepción y el método load () nunca devuelve null.
El método get () devuelve null si el objeto no se puede encontrar. El método load () puede devolver un proxy en lugar de una instancia real persistente get () nunca devuelve un proxy.
session.load () siempre devolverá un "proxy" (término Hibernate) sin tocar la base de datos. En Hibernate, proxy es un objeto con el valor del identificador dado, sus propiedades aún no se han inicializado, simplemente se ve como un objeto falso temporal. Si no se encuentra una fila, arrojará una ObjectNotFoundException.
session.get () siempre golpea la base de datos y devuelve el objeto real, un objeto que representa la fila de la base de datos, no el proxy. Si no se encuentra una fila, devuelve nulo.
El rendimiento con estos métodos también hace diff. entre dos...