Soy un novato en Java Persistence API e Hibernate.
¿Cuál es la diferencia entre FetchType.LAZYy FetchType.EAGERen Java Persistence API?
Soy un novato en Java Persistence API e Hibernate.
¿Cuál es la diferencia entre FetchType.LAZYy FetchType.EAGERen Java Persistence API?
Respuestas:
A veces tienes dos entidades y hay una relación entre ellas. Por ejemplo, puede tener una entidad llamada
Universityy otra entidad llamadaStudenty una universidad puede tener muchos estudiantes:La entidad universitaria puede tener algunas propiedades básicas, como id, nombre, dirección, etc., así como una propiedad de colección llamada estudiantes que devuelve la lista de estudiantes de una universidad determinada:
Ahora, cuando carga una universidad desde la base de datos, JPA carga sus campos de identificación, nombre y dirección por usted. Pero tiene dos opciones sobre cómo deben cargarse los estudiantes:
getStudents()método de la universidad .Cuando una universidad tiene muchos estudiantes, no es eficiente cargar a todos sus estudiantes junto con ella, especialmente cuando no son necesarios y, en tales casos, puede declarar que desea que los estudiantes se carguen cuando realmente se necesitan. Esto se llama carga diferida.
Aquí hay un ejemplo, donde
studentsestá marcado explícitamente para cargarse con entusiasmo:Y aquí hay un ejemplo donde
studentsestá marcado explícitamente para ser cargado perezosamente:fuente
getStudents(). Ej. ), Pero a veces esto no es posible, porque para cuando este método se llama, la sesión ya está cerrada y la entidad separada. Del mismo modo, a veces tenemos una arquitectura cliente / servidor (por ejemplo, cliente Swing / servidor JEE) y las entidades / DTO se transfieren a través del cable al cliente y nuevamente en estos escenarios la carga diferida no funcionará debido a la forma en que las entidades se serializan a través del cable.getStudents()método por primera vez, ¿se guardan en caché los resultados? para poder acceder a esos resultados más rápido la próxima vez?Básicamente,
fuente
EAGERla carga de colecciones significa que se recuperan completamente en el momento en que se recupera su padre. Entonces, si tieneCoursey tieneList<Student>, todos los estudiantes se obtienen de la base de datos en el momento en queCoursese obtiene.LAZYpor otro lado, significa que los contenidos de losListarchivos solo se obtienen cuando intenta acceder a ellos. Por ejemplo, llamandocourse.getStudents().iterator(). Llamar a cualquier método de acceso en elListiniciará una llamada a la base de datos para recuperar los elementos. Esto se implementa creando un Proxy alrededor deList(oSet). Entonces, para sus colecciones perezosas, los tipos concretos no sonArrayListyHashSet, sinoPersistentSetyPersistentList(oPersistentBag)fuente
course.getStudents(), dispara una consulta SQL (lo vi en la consola). En el tipo de recuperación diferida también, sucede lo mismo. Entonces, ¿cuál es la diferencia?fetchtype = LAZYel predeterminado, incluso si intenta obtener la colección con el getter hibernete arroja un error diciéndome que no puede evaluarPuedo considerar el rendimiento y la utilización de la memoria. Una gran diferencia es que la estrategia de recuperación EAGER permite utilizar objetos de datos recuperados sin sesión. ¿Por qué?
Todos los datos se obtienen cuando los datos marcados ansiosos en el objeto cuando se conecta la sesión. Sin embargo, en el caso de una estrategia de carga diferida, el objeto marcado de carga diferida no recupera datos si la sesión se desconecta (después de la
session.close()declaración). Todo lo que puede hacer el proxy de hibernación. La estrategia entusiasta permite que los datos sigan disponibles después de cerrar la sesión.fuente
Según mi conocimiento, ambos tipos de búsqueda dependen de sus requisitos.
FetchType.LAZYestá bajo demanda (es decir, cuando requerimos los datos).FetchType.EAGERes inmediato (es decir, antes de que llegue nuestro requisito, estamos recuperando el registro innecesariamente)fuente
De forma predeterminada, para todos los objetos de colección y mapa, la regla de obtención es
FetchType.LAZYy para otras instancias sigue laFetchType.EAGERpolítica.En resumen,
@OneToManyy las@ManyToManyrelaciones no obtienen los objetos relacionados (colección y mapa) implícitamente, pero la operación de recuperación se conecta en cascada a través del campo en@OneToOney@ManyToOneunos.(cortesía: - objectdbcom)
fuente
Ambos
FetchType.LAZYyFetchType.EAGERse utilizan para definir el plan de recuperación predeterminado .Desafortunadamente, solo puede anular el plan de recuperación predeterminado para la recuperación PERFECTA. La obtención de EAGER es menos flexible y puede generar muchos problemas de rendimiento .
Mi consejo es contener el impulso de hacer que sus asociaciones sean EAGER porque buscar es una responsabilidad de tiempo de consulta. Por lo tanto, todas sus consultas deben usar la directiva fetch para recuperar solo lo necesario para el caso de negocios actual.
fuente
Del Javadoc :
Por ejemplo, ansioso es más proactivo que perezoso. Lazy solo ocurre en el primer uso (si el proveedor toma la indirecta), mientras que con cosas ansiosas (puede) pretrabarse.
fuente
El
Lazytipo de recuperación se selecciona de forma predeterminada por Hibernate a menos que marque explícitamente elEagertipo de recuperación. Para ser más exacto y conciso, la diferencia se puede establecer de la siguiente manera.FetchType.LAZY= Esto no carga las relaciones a menos que lo invoque a través del método getter.FetchType.EAGER= Esto carga todas las relaciones.Pros y contras de estos dos tipos de búsqueda.
Lazy initializationmejora el rendimiento al evitar cálculos innecesarios y reduce los requisitos de memoria.Eager initializationrequiere más consumo de memoria y la velocidad de procesamiento es lenta.Dicho esto, depende de la situación, cualquiera de estas inicializaciones puede ser utilizada.
fuente
getMemberse llame a una función llamada que coincida exactamente con el patrón de nombre del miembro?Book.java
Sujeto.java
HibernateUtil.java
Main.java
Verifique el método retrieve () de Main.java. Cuando obtengamos Asunto, su lista de colección Libros , anotada con
@OneToMany, se cargará perezosamente. Pero, por otro lado, la asociación de libros relacionada con el tema de la colección , anotada con@ManyToOne, se carga de manera importante (por[default][1]para@ManyToOne,fetchType=EAGER). Podemos cambiar el comportamiento colocando fetchType.EAGER en@OneToManySubject.java o fetchType.LAZY@ManyToOneen Books.java.fuente
Fuente
fuente
Quiero agregar esta nota a lo que "Kyung Hwan Min" dijo anteriormente.
Supongamos que está utilizando Spring Rest con este simple arquitecto:
Y desea devolver algunos datos al front-end, si está utilizando
FetchType.LAZY, obtendrá una excepción después de devolver los datos al método del controlador ya que la sesión se cierra en el Servicio, por loJSON Mapper Objectque no puede obtener los datos.Hay tres opciones comunes para resolver este problema, depende del diseño, el rendimiento y el desarrollador:
FetchType.EAGER, para que la sesión siga viva en el método del controlador.FetchType.LAZYmétodo convertidor para transferir datos desdeEntityotro objeto de datosDTOy enviarlo al controlador, por lo que no hay excepción si la sesión se cierra.fuente
Hola, he adjuntado 2 fotos para ayudarte a entender esto.
fuente
@ drop-shadow si está utilizando Hibernate, puede llamar
Hibernate.initialize()cuando invoque elgetStudents()método:fuente
Perezoso: recupera las entidades secundarias de forma perezosa, es decir, al momento de recuperar la entidad principal, solo obtiene el proxy (creado por cglib o cualquier otra utilidad) de las entidades secundarias y cuando accede a cualquier propiedad de la entidad secundaria, en realidad es recuperado por hibernación.
EAGER: recupera las entidades secundarias junto con la principal.
Para una mejor comprensión, vaya a la documentación de Jboss o puede usar
hibernate.show_sql=truesu aplicación y verificar las consultas emitidas por la hibernación.fuente