persistencia implementar guia ejemplo configurar anotaciones java hibernate

java - implementar - Cómo evitar que Hibernate busque con entusiasmo objetos asociados muchos a uno



implementar hibernate en java (6)

Al usar las anotaciones de Hibernate, al poner @ManyToOne (fetch = FetchType.LAZY) en la asociación, se logra lo que se desea. ¿Has probado configurar fetch = "lazy" para ver si funciona?

Tengo una propiedad en un objeto de dominio que se declara en un elemento muchos a uno. La sintaxis básica de esta propiedad se ve así:

<many-to-one name="propertyName" class="propertyClass" fetch="select" not-found="ignore" lazy="proxy" />

Ahora, la idea es que Hibernate NO busque ansiosamente esta propiedad. Puede ser nulo, por lo que se establece el ignorar no encontrado.

Pero, Hibernate, al cargar la clase que contiene esta asociación, se encarga de cargar la instancia de la clase real (ni siquiera un proxy) cuando se carga la clase principal. Dado que algunas propiedades tienen más de 1 MB de tamaño, ocupan gran parte del espacio de almacenamiento dinámico.

Sin embargo, si no encontrado está configurado como excepción (o predeterminado a excepción), las clases padre que tienen esta propiedad cargan un proxy.

¿Cómo puedo detener la hibernación de no cargar un proxy, mientras sigo permitiendo que esta propiedad sea nula?

Encontré lazy = no-proxy, pero la documentación habla de algún tipo de modificación de bytecode y no entra en detalles. ¿Alguien me puede ayudar?

Si es importante, es la versión Java de Hibernate, y al menos es la versión 3 (puedo buscar la versión actual si me sirve, pero por ahora es Hibernate 3+).

No especifiqué antes, pero la versión de Java es 1.4. Por lo tanto, las anotaciones Java no son compatibles.


Si pasa el objeto de hibernación del modelo a la vista a través del controlador, ¡no lo haga!

En su lugar, cree un "objeto de instantánea" para almacenar los valores del objeto Hibernate que desea pasar a la vista y que se muestren.

¿Por qué? El proxy aún puede recuperar los valores cuando está en el controlador ... pero cuando pasa el proxy / objeto a la vista ya no puede recuperar los valores porque la transacción ya ha finalizado. Y es por eso que he sugerido lo que tengo arriba.


@Miguel Ping: Creo que la página a la que se refiere es [ http://www.hibernate.org/162.html] . Por lo que yo entiendo, el SELECCIONAR adicional es necesario en el caso del lado uno a uno, donde la clave externa no está presente. El ajuste constrained="true" le dice a Hibernate que el otro lado siempre está presente y que no se necesita ningún SELECT adicional.

Entonces, para el lado muchos a uno, donde reside la clave externa, no debería ser necesario ejecutar otro SELECT ya que el valor del FK indica si el otro extremo está presente o es null . Al menos, así es como lo entiendo.

Hasta ahora para la teoría. El proxy funciona para mí en el lado de la clave externa / de muchos a uno. El mapeo utilizado para la asociación es:

<many-to-one name="haendler" column="VERK_HAENDLOID" lazy="proxy" />

Pero el proxy no funciona para mí en el lado uno-a-uno usando un mapeo como el descrito en la URL dada ( constrained="true" ). Hmm, creo que abriré una pregunta para esto. ;-)


Encontré lazy = no-proxy, pero la documentación habla de algún tipo de modificación de bytecode y no entra en detalles. ¿Alguien me puede ayudar?

Asumiré que estás usando ANT para construir tu proyecto.

<property name="src" value="/your/src/directory"/><!-- path of the source files --> <property name="libs" value="/your/libs/directory"/><!-- path of your libraries --> <property name="destination" value="/your/build/directory"/><!-- path of your build directory --> <fileset id="applibs" dir="${libs}"> <include name="hibernate3.jar" /> <!-- include any other libraries you''ll need here --> </fileset> <target name="compile"> <javac srcdir="${src}" destdir="${destination}" debug="yes"> <classpath> <fileset refid="applibs"/> </classpath> </javac> </target> <target name="instrument" depends="compile"> <taskdef name="instrument" classname="org.hibernate.tool.instrument.javassist.InstrumentTask"> <classpath> <fileset refid="applibs"/> </classpath> </taskdef> <instrument verbose="true"> <fileset dir="${destination}"> <!-- substitute the package where you keep your domain objs --> <include name="/com/mycompany/domainobjects/*.class"/> </fileset> </instrument> </target>


¡Asegúrate de que tu clase no sea final!


Si el otro extremo de la asociación puede ser nulo , creo que hibernate debe consultar el extremo de la asociación para determinar si debe usar un proxy o no (sin necesidad de proxy si el otro extremo es nulo ). No puedo encontrar la referencia a esto ahora, pero recuerdo haberlo leído en alguna parte.

Para proporcionar carga lenta de los campos, la documentación se refiere a las mejoras de los códigos de bytes en los campos en tiempo de compilación: Utilización de la recuperación de propiedades diferidas . Aquí hay un extracto:

Hibernate3 admite la recuperación diferida de propiedades individuales. Esta técnica de optimización también se conoce como grupos de búsqueda. Tenga en cuenta que esto es principalmente una función de marketing, ya que en la práctica, optimizar las lecturas de filas es mucho más importante que la optimización de lecturas de columna. Sin embargo, solo cargar algunas propiedades de una clase puede ser útil en casos extremos, cuando las tablas heredadas tienen cientos de columnas y el modelo de datos no se puede mejorar.

¡La carga de propiedades vagas requiere la instrumentación de bytecode de compilación! Si sus clases persistentes no son mejoradas, Hibernate ignorará silenciosamente la configuración de propiedad perezosa y volverá a la recuperación inmediata.