Pregunta

Tengo un objeto de dominio Hibernate que se carga por diferentes partes de la aplicación. A veces es ventajoso carga perezosa todas las asociaciones y otros que es mejor para cargar toda la cosa en una unan. Como solución de compromiso con suerte feliz que he encontrado:

Uso de la recuperación en lotes, Hibernate puede cargar varios proxies sin inicializar si se accede a un proxy. la recuperación en lotes es una optimización de la estrategia de selección de la recuperación perezosa.

hibernate.default_batch_fetch_size :

  

Uso de la recuperación en lotes, Hibernate puede cargar varios proxies sin inicializar   si se accede a un proxy. la recuperación en lotes es una optimización de la   perezoso seleccione estrategia de recuperación.

También ver:

hibernate.jdbc.fetch_size:

  

Un valor distinto de cero determina el JDBC traiga tamaño (llamadas Statement.setFetchSize ()).

Bien es Hibernate lo suficientemente inteligente como para buscar en la memoria caché de segundo nivel al hacer la recuperación en lotes? es decir Realice una de extracciones de la llamada inicial a la asociación y luego los próximos llamadas X dio en el caché? De esa manera puedo tener la carga diferida deseo sino también golpear el caché a menudo por las transacciones más volumen similar.

Si todo el contenido de la colección ya está contenido en la memoria caché, ¿seguiría ejecutar las consultas ir a buscar en el acceso de la colección?

Gracias.

¿Fue útil?

Solución

Hice un montón de investigación hoy en día y fue capaz de desenterrar una respuesta a mi propia pregunta. Yo estaba buscando a través del código de Hibernate y el flujo se ve así:

es la colección inicializado?

  • No? No traiga un lote (artículos obtenidos por lotes-fetch se colocan en la caché)
  • Si? Mira en la memoria caché para ese caso particular, si no es así no hacen un lote captación.

Así que si el elemento de la colección que está buscando se encuentra en la caché, entonces el lote-fetch no sucede. Si el artículo no se encuentra en la caché de segundo nivel, entonces el lote de Fetch sucede, pero lo hará una zona de alcance de los artículos por lotes, independientemente de si los artículos apilados están en la memoria caché.


----- Ejemplo 1 -----

Lo bueno:

(Tres elementos de una colección - tamaño de lote de 3) La primera vez:

  • collection.getItem (0) - Sin caché | batch-fetch 3 artículos
  • collection.getItem (1) - Cargado en por lotes-fetch
  • collection.getItem (2) - Cargado en por lotes-fetch

Ahora, en otro lugar, más tarde en el tiempo:

  • collection.getItem (0) - Cache Hit
  • collection.getItem (1) - Cache Hit
  • collection.getItem (2) - Cache Hit

----- Ejemplo 2 -----

Lo malo:

(Tres elementos de una colección - tamaño de lote de 3)

En este caso, el elemento en el índice 0 se elimina de la memoria caché porque tal vez la caché estaba lleno y el elemento se ha caído, o el artículo fue rancio o inactivo.

  • collection.getItem (0) - No en caché también lo hacen por lotes de 3 (??? * Seleccionar donde id en (,))
  • collection.getItem (1) - en la memoria caché Ya (sustituido por lotes-fetch de todos modos)
  • collection.getItem (2) - en la memoria caché Ya (sustituido por lotes-fetch de todos modos)

Así que el comercio fuera de aquí es que usted tendrá menos llamadas SQL debido a procesamiento por lotes, pero se le echa en falta se hace una caché más a menudo. Hay un billete abierto para tener el aspecto de procesamiento por lotes en la memoria caché de segundo nivel antes de que salga a la base de datos.

http://opensource.atlassian.com/projects/hibernate/browse / HHH-1775

votar para arriba!

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