Hibernate 2º nivel de caché de objetos que son perezosos=false, el resultado de un defecto fetch=unir, se documenta en cualquier lugar?

StackOverflow https://stackoverflow.com/questions/1968767

Pregunta

Tengo la experiencia de la siguiente aparentemente indocumentados problema, y quiero entender si

  1. Hice algo mal
  2. ¿Alguien se encuentre con el mismo problema?
  3. Es que realmente no documentado en ninguna parte?o ¿me olvido de algo?

El comportamiento es esta Supongamos la siguiente asignación

<class name="org.sample.Foo" table="foo">
    ...
   <many-to-one name="bar" class="org.sample.Bar"/>
</class>


<class name="org.sample.Bar" table="bar" lazy="false">
    ...
</class>

En primer lugar, como un fondo, Hibernate valor predeterminado para el fetch atributo en una relación debe ser "seleccione", esto es al menos lo que se documenta (voy a añadir el enlace aquí cuando me lo encuentro)

Sin embargo, al parecer, esto es cierto sólo si la referencia de clase es lazy="true"!

así que al parecer la anterior asignación se traduce en esto (porque la Barra es lazy="false"):

<class name="org.sample.Foo" table="foo">
    ...
   <many-to-one name="bar" class="org.sample.Bar" *fetch="join" />
</class>


<class name="org.sample.Bar" table="bar" lazy="false">
    ...
</class>

Ahora, ¿por qué tendría que ser un problema?en lugar de 2, selecciona, Hibernate cargar el no perezoso de referencia en un solo select con su "padre" (carga de Foo con el Bar en un solo select)

en realidad, esto tiene sentido, ya que el objeto no es perezoso, ¿por qué no carga?

La respuesta es esta:¿qué sucede si la Barra está en el 2º nivel de caché?

<class name="org.sample.Foo" table="foo">
    ...
   <many-to-one name="bar" class="org.sample.Bar" *fetch="join" />
</class>


<class name="org.sample.Bar" table="bar" lazy="false">
    <cache usage="transactional" />
    ...
</class>

Y la respuesta es - no cambia nada!

Al parecer, uno podría asumir Hibernate es lo suficientemente inteligente como para entender que los objetos de este tipo, no debe ser cargado, pero desde el default de captura fue cambiado de seleccionar a unirse, Hibernate no tiene otra opción (que no puede unirse a una mesa real con el 2º nivel de caché, sin embargo)

modo de Hibernación hace lo que se le dice, y utiliza una combinación para ir a buscar un objeto de la base de datos donde se encuentra ya en el 2º nivel de caché

La solución que he encontrado es, literalmente, cambiar la asignación a fetch="seleccionar"

Ahora, cuando el segundo para seleccionar la Barra está a punto de ir, Hibernate entiende que no debe ir a la base de datos, y se obtiene de la caché.y sólo 1 consulta se ejecutará (después del calentamiento)

¿Fue útil?

Solución

Me encontré con el mismo problema, y me encontré marcar todos los muchos-a-uno, las relaciones que se almacenarán en caché fetch="select".En el momento de la consulta se construye, Hibernate no sabe si la instancia solicitada de la Barra está en la caché de segundo nivel o no (suponiendo que Foo no está en la caché).

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