Comportamiento extraño en Hibernate encontrar Por Id query

Tengo un caso de uso donde Hibernate se comporta de una manera inesperada. La idea es que tengo una entidad con asociaciones (aunque muchas de ellas, con muchos a uno y uno a muchos enlaces) y quiero hacer un hallazgo ById consulta usando la clave principal de una de las entidades. El problema es que la entidad resultante no tiene una de las entidades asociadas de TOOne (de nuevo, este es el caso de la entidad relacionada más grande). Como más contexto, la entidad base (la utilizada para el hallazgoPor consulta) también tiene un par de campos de "texto libre", mapeado como VARCHAR(1000) en mysql. Lo raro en este caso son los siguientes:

  1. Este problema sólo ocurre para una pequeña muestra de entradas de tabla. El 90% de ellos acaba de recuperar el árbol entero sin problemas
  2. Tomar la consulta generada por hibernate y utilizarla en mysql resultará en un objeto correctamente ligado (el id de la entidad asociada se recupera en esta unión) incluso para este id "problemático" - título por lo que el SQL generado es correcto
  3. La entrada en cuestión tiene algunos textos más largos en las 2 columnas VARCHAR(1000) (uno es ~ 300 caracteres, el otro es ~ 500 caracteres). Si recortamos uno de los textos a cierta longitud de caracteres, la consulta es exitosa para este id también. Seguir adelante, si disminuimos los caracteres del otro campo de "texto libre", podemos aumentar los caracteres para el primer campo de texto con la misma cantidad de caracteres y la recuperación seguirá siendo exitosa. Un personaje más y la consulta no recuperará la entidad relacionada. Ir aún más lejos, optimizando algunas de las relaciones (haciendo algunas asociaciones "ToOne" como perezosas) permitirá añadir más caracteres a los campos de "texto libre" sin afectar la recuperación.

La solución inmediata en este caso es más probable que rediseñe cuidadosamente las asociaciones y cuánto del árbol se recupera con cada consulta, pero tengo más curiosidad sobre este comportamiento del marco Hibernado. ¿Tiene algo como un límite a cuántos datos/objetos puede devolver o hidratarse para una sola consulta de fetch? Si es así, ¿cuál es el límite y puede ser empapado?

Marco utilizado: Hibernate 5.3.9, Datos de primavera 2.1.6, Java 8, Mysql 5.7 base de datos

Gracias.

Pregunta hecha hace 3 años, 4 meses, 27 días - Por compilercaptain


2 Respuestas:

  • El comportamiento que estás experimentando puede estar relacionado con la configuración de Hibernate, particularmente con la carga perezosa y la profundidad de las asociaciones que se están recuperando en una sola consulta.

    En Hibernate, cuando se realizan consultas para recuperar entidades que tienen asociaciones, se debe tener en cuenta si esas asociaciones están configuradas como "fetch eager" o "fetch lazy". Si una asociación está configurada como "fetch eager", Hibernate intentará recuperar todas las asociaciones relacionadas en la misma consulta, lo que puede resultar en una gran cantidad de datos cargados en memoria.

    Una posible explicación para el comportamiento extraño que estás experimentando podría ser que, para las entradas de tabla que funcionan correctamente, las asociaciones están configuradas de manera que se cargan de forma eficiente, sin sobrecargar la memoria. Sin embargo, para las entradas problemáticas, la carga de datos es excesiva y podría provocar problemas al cargar las entidades asociadas.

    Para abordar este problema, te recomendaría revisar la configuración de las asociaciones en tus entidades y considerar cambiar algunas de ellas a "fetch lazy" si no necesitas recuperar esas asociaciones automáticamente en cada consulta. También puedes utilizar consultas específicas para cargar selectivamente las asociaciones que necesitas en lugar de recuperar todo el árbol de entidades en una sola consulta.

    En cuanto a si Hibernate tiene un límite en la cantidad de datos/objetos que puede devolver en una sola consulta de fetch, no hay un límite estricto establecido por Hibernate. Sin embargo, es importante tener en cuenta la eficiencia de las consultas y la carga de datos en memoria para evitar problemas de rendimiento.

    Espero que esta información te sea útil para abordar el comportamiento inesperado que estás experimentando con Hibernate. Si necesitas más ayuda o información, no dudes en preguntar.

    Respondida el Dec 19, 2020 a las 19:40 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Posibles causas y soluciones:

    1. Límite de tamaño de objeto de Hibernate:

    Hibernate tiene un límite predeterminado de 10000 bytes para el tamaño del objeto devuelto por una consulta. Para entidades con muchas asociaciones y campos de texto libre grandes, esto puede superarse.

    Solución: Aumenta el límite de tamaño del objeto de Hibernate utilizando la propiedad hibernate.max_fetch_depth.

    2. Caché de segundo nivel:

    La caché de segundo nivel puede almacenar objetos parcialmente inicializados, lo que puede provocar problemas al recuperar entidades con asociaciones múltiples.

    Solución: Deshabilita la caché de segundo nivel para la entidad problemático configurando @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE).

    3. Limitaciones de la base de datos:

    Algunas bases de datos, como MySQL, tienen límites en el tamaño de los resultados de las consultas. Para consultas complejas que recuperan muchos datos, esto puede ser un problema.

    Solución: Optimiza la consulta para recuperar solo los datos necesarios. Utiliza técnicas de unión y criterios para limitar la cantidad de datos recuperados.

    4. Problemas de concurrencia:

    Si la entidad se modifica simultáneamente por múltiples transacciones, puede provocar problemas al recuperar el estado correcto.

    Solución: Utiliza una estrategia de bloqueo adecuada para garantizar la coherencia de los datos.

    5. Configuraciones personalizadas:

    Verifica si has configurado alguna propiedad personalizada en Hibernate que pueda afectar el comportamiento de consulta. Por ejemplo, la propiedad hibernate.default_batch_fetch_size puede limitar la cantidad de entidades recuperadas por lote.

    6. Problemas de mapeo:

    Asegúrate de que el mapeo de tu entidad sea correcto y no haya errores que puedan afectar la recuperación de asociaciones.

    7. Depuración adicional:

    Habilita la depuración de consultas de Hibernate para ver el SQL generado. Utiliza un depurador para inspeccionar el estado de los objetos devueltos y las asociaciones.

    Nota: El límite de Hibernate para el tamaño del objeto es una estimación y puede variar según el tamaño y la complejidad de los objetos devueltos. Es posible que debas aumentar el límite gradualmente hasta que encuentres un valor que funcione para tu caso particular.

    Respondida el Dec 19, 2020 a las 19:51 - por Gemini

    Votos positivos: 0 | Votos negativos: 0