hibernate - framework - spring mvc 4 tutorial español
Hibernate: carga perezosa uno a uno, opcional=falso (2)
El más simple es falsificar la relación de uno a muchos. Esto funcionará porque la carga diferida de la recopilación es mucho más fácil que la carga diferida de la propiedad anulable única, pero en general esta solución es muy inconveniente si utiliza consultas complejas de JPQL / HQL.
El otro es usar instrumentación de bytecode de tiempo de compilación. Para más detalles, lea la documentación de Hibernate: 19.1.7. Usar la recuperación de propiedades perezosas. Recuerde que en este caso debe agregar la @LazyToOne(LazyToOneOption.NO_PROXY)
a la relación de uno a uno para que sea floja. Establecer fetch en LAZY no es suficiente.
La última solución es usar instrumentación de bytecode en tiempo de ejecución, pero solo funcionará para aquellos que usan Hibernate como proveedor JPA en un entorno JEE completo (en tal caso, configurar " hibernate.ejb.use_class_enhancer
" en true debería ser el truco: Entity Manager Configuration ) o utilice Hibernate con Spring configurado para realizar el tejido en tiempo de ejecución (esto puede ser difícil de lograr en algunos servidores de aplicaciones anteriores). En este caso, también se requiere la anotación @LazyToOne(LazyToOneOption.NO_PROXY)
.
Me enfrenté al problema de que la carga lenta uno a uno no funciona en hibernación. Ya lo resolví , pero todavía no entiendo lo que sucede.
Mi código (la carga lenta no funciona aquí , cuando selecciono Persona: también se busca la dirección):
@Entity
public class Person{
@Id
@SequenceGenerator(name = "person_sequence", sequenceName = "sq_person")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "person_sequence")
@Column(name = "id")
private long personID;
@OneToOne(mappedBy="person", cascade=CascadeType.ALL, fetch = FetchType.LAZY)
private Adress address;
//.. getters, setters
}
@Entity
public class Address {
@Id
@Column(name="id", unique=true, nullable=false)
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property", value="person"))
private long personID;
@PrimaryKeyJoinColumn
@OneToOne
private FileInfo person;
}
Pero : si agrego optional=false
en la relación OneToOne, ¡la carga lenta funciona bien !
@OneToOne(mappedBy="person", cascade=CascadeType.ALL, optional = false, fetch = FetchType.LAZY)
private Adress address;
Pregunta / Elogio: por favor, explíqueme cómo optional=false
anotación optional=false
ayuda a lograr la carga diferida.
PD . He leído publicaciones post1 y post2 , y entiendo por qué el OneToOne simple no puede ser flojo, pero aún no puedo entender la magia optional=false
.
Si la asociación es opcional, Hibernate no tiene manera de saber si existe una dirección para una persona determinada sin emitir una consulta. Por lo tanto, no puede rellenar el campo de dirección con un proxy, ya que no podría haber destinatarios que hagan referencia a la persona, y no puede poblarlo con nulo, porque podría haber una dirección que haga referencia a la persona.
Cuando hace obligatoria la asociación (es decir, optional=false
), confía en usted y asume que existe una dirección, ya que la asociación es obligatoria. Por lo tanto, rellena directamente el campo de dirección con un proxy, sabiendo que hay una dirección que hace referencia a la persona.