Pregunta

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!

¿Fue útil?

Solución

Del Foro de Hibernate :

  

Esto del libro Hibernate in Action. Bueno, lee esto ...


Recuperando 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 forma exclusiva un solo instancia de una clase. Por lo tanto, es común que las aplicaciones utilicen el identificador como Mango conveniente para un objeto persistente. La recuperación por identificador puede usar el caché al recuperar un objeto, evitando un impacto en la base de datos si el objeto ya está en 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 al usuario solicitud. La diferencia es trivial:

Si load () no puede encontrar el objeto en el caché o la base de datos, una excepción es arrojado El método load () nunca devuelve nulo. El método get () devuelve nulo si no se puede encontrar el objeto.

El método load () puede devolver un proxy en lugar de una instancia persistente real. Un proxy es un marcador de posición que activa la carga del objeto real cuando está accedido por primera vez; Sobre el Por otro lado, get () nunca devuelve un proxy. Elegir entre get () y load () es fácil: si está seguro de que persiste existe un objeto, y la inexistencia se consideraría excepcional, load () es un Buena opcion. Si no está seguro de que haya una instancia persistente con el dado identificador, use get () y pruebe el valor de retorno para ver si es nulo. Usar load () tiene Otra implicación: la aplicación puede recuperar una referencia válida (un proxy) a un instancia persistente sin golpear la base de datos para recuperar su estado persistente. Asi que Es posible que load () no arroje una excepción cuando no encuentra el objeto persistente en el caché o la base de datos; la excepción se lanzaría más tarde, cuando el proxy Se accede. Por supuesto, recuperar un objeto por identificador no es tan flexible como usar arbitrario consultas

Otros consejos

Bueno, al menos en nhibernate, session.Get (id) cargará el objeto desde la base de datos, mientras que session.Load (id) solo crea un objeto proxy sin abandonar su servidor. Funciona igual que cualquier otra propiedad con carga lenta en sus POCO (o POJOs :). Luego puede usar este proxy como referencia al objeto mismo para crear relaciones, etc.

Piense en ello como si tuviera un objeto que solo mantiene la 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á.

session.load () siempre devolverá un "proxy" (término de Hibernate) sin tocar la base de datos. En Hibernate, el proxy es un objeto con el valor identificador dado, sus propiedades aún no se han inicializado, solo parece un objeto falso temporal.     Si no se encuentra ninguna 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 ninguna fila, devuelve nulo.

El rendimiento con estos métodos también hace diff. entre dos ...

Un punto adicional más ::

el método get de la clase Hibernate Session devuelve nulo si el objeto no se encuentra en la memoria caché ni en la base de datos. mientras que el método load () arroja ObjectNotFoundException si el objeto no se encuentra en la memoria caché, así como en la base de datos, pero nunca devuelve nulo.

Una consecuencia indirecta del uso de " load " en lugar de "obtener" es que el bloqueo optimista usando 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 versión no se carga. La versión solo se cargará cuando / si luego se refiere a una propiedad en el objeto, activando 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 comprobación de bloqueo optimista, por lo que la actualización de su 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]

Realmente queremos que la confirmación de la sesión 1 falle con una excepción de bloqueo optimista, pero tendrá éxito aquí.

Usando " get " en lugar de " cargar " 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.

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 estamos seguros de que el objeto existe.

Una excelente explicación se encuentra en http: // www.mkyong.com/hibernate/different-between-session-get-and-session-load
session.load ():
Siempre devolverá un & # 8220; proxy & # 8221; (Término de Hibernate) sin tocar la base de datos.
En Hibernate, el proxy es un objeto con el valor de identificador dado, sus propiedades aún no se han inicializado, solo parece 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, llegará a la base de datos con la instrucción select. Si no se encuentra ninguna fila, se lanzará una ObjectNotFoundException.
session.get ():
Siempre golpea la base de datos (si no se encuentra en la memoria caché) y devuelve el objeto real, un objeto que representa la fila de la base de datos, no el proxy.
Si no se encuentra ninguna fila, devuelve nulo.

load () no puede encontrar el objeto desde el caché o la base de datos, se genera una excepción y el método load () nunca devuelve nulo.

El método

get () devuelve un valor nulo si no se puede encontrar el objeto. El método load () puede devolver un proxy en lugar de una instancia persistente real get () nunca devuelve un proxy.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top