two tables query left inner java hibernate jpa join

java - tables - jpql left join



JPA/Hibernate cantidad máxima de uniones? (5)

¿Hay un límite en el número de combinaciones permitidas en una consulta JPA / Hibernate?

Dado que Hibernate no se une automáticamente , debo especificar explícitamente las uniones en mi consulta JPA / Hibernate. Por ejemplo, la persona tiene una dirección, una dirección tiene un estado. La siguiente consulta recupera persona (s) con dirección y estado completamente cargado:

select p, a, s from person p left join p.address a left join a.state s where ...

A medida que continúo agregando combinaciones, finalmente (después de 12-13 uniones de la izquierda) alcanzo un límite donde Hibernate genera SQL no válido:

Caused by: java.sql.SQLException: Column ''something69_2_'' not found.

Tengo el dialecto de Hibernate configurado para la implementación de mi base de datos, MySQL:

<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>

¿Existe un límite en el número de combinaciones que Hibernate puede manejar en una sola consulta?

Editar 1: Lo siguiente está en el archivo de registro:

could not read column value from result set: something69_2_; Column ''something69_2_'' not found.

Sin embargo, something69_2_ no aparece en la consulta SQL. Es como si Hibernate hubiera generado una consulta SQL y espera que something69_2_ esté en los resultados, que no lo es.

Edición 2: problema similar documentado como un error de Hibernate no fijado HHH-3035

Edición 3: Este es un error documentado de Hibernate HHH-3636 , que se ha corregido pero que aún no forma parte de ninguna versión.

Edición 4: construí hibernate-core 3.3.2-SNAPSHOT que incluye la corrección de errores HHH-3636 y no resolvió este problema.

Editar 5: El comportamiento de error parece ser desencadenado por múltiples LEFT JOIN FETCH UNIR LEFT JOIN FETCH en relaciones ManyToMany o OneToMany. Uno funcionará, dos o tres resultados en el error.

Editar 6: Aquí está el seguimiento de la pila:

javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute query at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:629) at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:73) Caused by: org.hibernate.exception.SQLGrammarException: could not execute query at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43) at org.hibernate.loader.Loader.doList(Loader.java:2214) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2095) at org.hibernate.loader.Loader.list(Loader.java:2090) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:388) at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338) at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172) at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121) at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79) at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:64) ... 69 more Caused by: java.sql.SQLException: Column ''something69_2_'' not found. at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926) at com.mysql.jdbc.ResultSetImpl.findColumn(ResultSetImpl.java:1136) at com.mysql.jdbc.ResultSetImpl.getInt(ResultSetImpl.java:2777) at org.hibernate.type.IntegerType.get(IntegerType.java:28) at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:113) at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:102) at org.hibernate.loader.Loader.getKeyFromResultSet(Loader.java:1088) at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:553) at org.hibernate.loader.Loader.doQuery(Loader.java:689) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224) at org.hibernate.loader.Loader.doList(Loader.java:2211) ... 77 more

Edición 7: El motivo de todas estas uniones es evitar que Hibernate realice n + 1 consultas, consulte las Preguntas frecuentes sobre Hibernate sobre ¿Cómo puedo evitar n + 1 SQL SELECT consultas cuando ejecuto una consulta Hibernate?


No hay nada dentro del código de Hibernate que limite el número de combinaciones. Esto podría ser un error en el dialecto o una limitación del motor de la base de datos. ¡Pero mi dinero está en un error no relacionado con el número de combinaciones! ¿Has intentado ejecutar el SQL directamente en una sesión de consulta interactiva?


Una vez alcancé el límite de la tabla de MySQL 5.0 61 con Hibernate:

ERROR 1116 (HY000): Too many tables; MySQL can only use 61 tables in a join


¿Has intentado ejecutar con el controlador jdbc real en uso? Podría ser un problema del controlador jdbc.

Aunque a juzgar por el nombre de la columna, está buscando, supongo que hay algunos ajustes / construcción de nombres que van mal. Definitivamente se parece más a un error que a un límite previsto.


La pregunta es por qué estás tratando de hacer una consulta tan compleja en primer lugar?

¿Has considerado diferentes enfoques? La documentación sobre la mejora del rendimiento hace algunas sugerencias.


¿Estás aliasing todas tus uniones internas? ¿Y usando esos alias? He visto un comportamiento realmente extraño con Hibernate cuando intentas usar el aliasing implícito en la cláusula SELECT para hacer cosas como esta (ejemplo extremadamente simplificado):

select p.address.state from person p

Pero si declaras explícitamente todos tus alias, funciona bien. Me gusta esto:

select s from person p join p.address a join a.state s

... o incluso esto:

select s from person p join p.address.state s