es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo evitar la carga tardía en JPA/Hibernate con FetchType.LAZY (especialmente al usar @Transactional)?

Busqué pero solo encuentro personas preguntando lo contrario a mi pregunta. Entonces digamos que tenemos:

@Entity
class Book {

@ManyToOne(fetch = FetchType.LAZY)
private Author author;
}

¿Hay alguna propiedad/manera (preferiblemente global) en JPA/Hibernate para evitar cargar perezosamente el autor (o cualquier entidad)?

No me malinterpreten, no quiero usar la búsqueda EAGER. Quiero evitar que los juniors puedan llamar accidentalmente a book.getAuthor().getName() y hacer otra llamada a la base de datos. Muchas personas están buscando solucionar su LazyInitializationException, pero básicamente quiero forzar que se produzca una excepción incluso si hay una sesión activa (lo cual es bastante fácil de hacer al usar @Transactional). Sin embargo, aún quiero que Author se obtenga si usas correctamente “JOIN FETCH Author” en tu consulta JPQL.

Mi caso de uso particular es con Spring y GraphQL.
@Transactional fácilmente oculta cuándo está abierta una sesión y evita la LazyInitializationException.
Y con GraphQL puedes especificar qué campos obtener, por lo que no quiero uniones innecesarias cuando no se solicitan dichos campos (aquí usamos un Field Resolver con un DataLoader).

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Desafortunadamente, no existe una propiedad global o forma en JPA/Hibernate para evitar la carga diferida de una entidad. La opción más cercana para lograr esto es utilizando herramientas de mejora de bytecode como el mejoramiento de bytecode de Hibernate o el mejoramiento de OpenJPA, que pueden ayudar a hacer cumplir la carga diferida y evitar excepciones en tiempo de ejecución. Sin embargo, este enfoque requiere configuración y preparación adicionales.

    Una solución para evitar que los programadores juniors llamen accidentalmente a book.getAuthor().getName() y realicen otra llamada a la base de datos es utilizar un enfoque de DTO (Objeto de Transferencia de Datos), donde se pueden especificar qué campos recuperar y evitar joins innecesarios. Este enfoque también ayuda a reducir el tamaño de la carga útil y mejorar el rendimiento.

    Otra solución es utilizar el gráfico de entidades de JPA para especificar qué atributos buscar y evitar la carga diferida. Se puede definir un gráfico de entidad nombrado para una entidad específica y reutilizarlo en la consulta JPQL para buscar solo los atributos requeridos.

    En resumen, no existe una forma directa de evitar la carga diferida de una entidad en JPA/Hibernate. Sin embargo, existen soluciones alternativas como utilizar DTOs o gráficos de entidades para buscar solo los atributos requeridos y evitar joins innecesarios.

Comments are closed.