Eso es el problema N más uno: una consulta carga las filas padre y luego tocar una asociación perezosa en cada una dispara otra consulta por fila. Se arregla trayendo la asociación en la misma consulta con un join fetch o un entity graph, poniendo un tamaño de batch fetch para que Hibernate cargue las asociaciones en grupos, o proyectando directamente a un DTO con solo las columnas que necesitas. Deja las asociaciones perezosas por defecto y decide el fetch por caso de uso.
Por qué lo preguntan los entrevistadores
Es el bug de rendimiento más común en aplicaciones con Spring e Hibernate, así que el entrevistador quiere saber si lo reconoces en los logs y lo arreglas sin volverlo todo eager. Quieren oír que la estrategia de fetch pertenece a la consulta y no al mapeo, más conciencia de los problemas relacionados: inicialización perezosa fuera de sesión, open session in view, y productos cartesianos al unir dos colecciones.
Cómo estructurar tu respuesta
- Nombra el patrón y explica qué dispara las consultas extra.
- Da los arreglos en orden: join fetch, entity graph, tamaño de batch, proyección.
- Insiste en que los mapeos siguen perezosos y son las consultas las que deciden el fetch.
- Menciona la detección: loguea el SQL o comprueba el número de consultas en los tests.
Ejemplo de respuesta
Es N más uno. Cargo una página de pedidos en una consulta, luego el serializador toca pedido.getItems en cada uno y, como la asociación es perezosa, Hibernate vuelve a por cada pedido. Veinte pedidos se convierten en veintiuna consultas, y solo aparece con datos reales. El primer arreglo es traer lo que necesito de una vez, o con una consulta con join fetch o con un entity graph nombrado en el método del repositorio, para que los ítems vengan con los padres. Si necesito dos colecciones separadas no hago join de ambas, porque eso multiplica filas en un producto cartesiano; en su lugar pongo un tamaño de batch fetch para que Hibernate las cargue en lotes de, digamos, cincuenta con una cláusula in, lo que son dos consultas en vez de cien. A menudo la respuesta real es que el endpoint no necesita entidades para nada, así que proyecto directamente a un DTO con solo las columnas necesarias. Lo que no hago es cambiar el mapeo a eager, porque eso arregla un endpoint y ralentiza todos los demás. Lo mantengo honesto comprobando el número de consultas en un test de integración.
¿Tienes esta entrevista a la vuelta de la esquina? GhostPilot escucha tu llamada en vivo, detecta la pregunta en cuanto la hacen y pone una respuesta estructurada en tu pantalla en tiempo real. Pruébalo en tu próxima entrevista de práctica, o coge un Session Pass de $29, sin suscripción, para la de verdad.
Mira cómo funcionaPreguntas de seguimiento que puedes esperar
- ¿Qué es una LazyInitializationException y cómo la evitas bien?
- ¿Por qué se considera dañino el open session in view?
- ¿Cómo paginarías una consulta que además hace join fetch de una colección?
Más preguntas para Desarrollador Java
Tu entrevistador hará su propia versión de esta. Pega la descripción real del puesto en el Question Predictor gratuito y obtén las 20 preguntas que ese puesto tiene más probabilidades de hacerte, con lo que cada una busca en realidad.
Predecir mis preguntas