He aprendido que Hibernate permite que los elementos secundarios para ser consultados sólo cuando es necesario a través de la utilización de Lazy Loading.
Así que si tenemos:
@Entity
public class Payment {
...
@ManyToOne(fetch = FetchType.LAZY)
private Debtor debtor;
}
Espero que cuando voy a buscar un Pago de la base de datos de hibernación establece un marcador de posición en el atributo deudor y obtiene el deudor sólo cuando es estrictamente necesario .
Así que si uso un método getter con el fin de conseguir un deudor de mi Pago del objeto:
Debtor debtor = payment.getDebtor();
Espero que las secuencias de roscado hasta que Hibernate realiza la consulta SELECT y devolver el objeto deudor.
Así que ¿por qué diablos Siempre tengo una excepción HibernateLazyLoading que me obliga a escribir una costumbre buscar a consulta en el PaymentRepository, ralentizando mi consulta inicial como me hubiera utilizado un fetchType EAGER ?
Entonces ¿por qué hace esto FetchType.LAZY
existe si no funciona como se esperaba, naturalmente?
Me gustaría especificar respuesta @Andronicus debido a que la respuesta no es correcta.
LazyInitializationException
No está estrictamente relacionado con @Transactional
, transacciones o conexiones abiertas / cerradas. El comportamiento es bastante simple (hay pseudo código de abajo)
Sin LazyInitializationException
Context context = Hibernate.openPersistentContext();
Payment payment = context.getById(1L, Payment.class);
Debtor debtor = payment.getDebtor();
Hibernate.closePersistentContext();
Con LazyInitializationException
Context context = Hibernate.openPersistentContext();
Payment payment = context.getById(1L, Payment.class);
Hibernate.closePersistentContext();
Debtor debtor = payment.getDebtor();
preguntas
Así que ¿por qué diablos Siempre tengo una excepción HibernateLazyLoading que me obliga a escribir una costumbre buscar a consulta en el PaymentRepository, ralentizando mi consulta inicial como me hubiera utilizado un fetchType EAGER?
Debido a Hibernate.closePersistentContext()
que ocurrió antes en alguna parte.
Entonces ¿por qué hace esto FetchType.LAZY existe si no funciona como se esperaba, naturalmente?
Debido a que no siempre necesitamos la totalidad neto de una entidad gráfica. Podemos utilizar JPQL (HQL), los criterios y las proyecciones para cargar partes de la entidad. Hay que explicar a Hibernate cómo se relacionan las entidades, por lo que hay que añadir las asociaciones, al igual que @ManyToOne
.
Hay un pequeño problema: el mapeo sirve para dos propósitos
- Explicar a Hibernate cómo se relacionan las entidades
- Guardar / Cargar entidades
Así que la forma más sencilla de carga de desconexión de los objetos de mapeo es FetchType.LAZY
.
La simple regla
Siempre use FetchType.LAZY
todas partes a buscar las partes necesarias de la gráfica entidad en el lugar donde son necesarios antes.