JPA/Hibernate 查询中允许的连接数是否有限制?
由于 Hibernate不会自动加入,因此我必须在 JPA/Hibernate 查询中明确指定联接。例如,人有地址,地址有状态。以下查询检索地址和状态已满载的人员:
select p, a, s from person p left join p.address a left join a.state s where ...
随着我不断添加连接,我最终(在 12-13 个左连接之后)达到了 Hibernate 生成无效 SQL 的限制:
Caused by: java.sql.SQLException: Column 'something69_2_' not found.
我确实为我的数据库实现 MySQL 设置了 Hibernate 的方言:
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
Hibernate 在单个查询中可以处理的连接数是否有限制?
编辑1:日志文件中包含以下内容:
could not read column value from result set: something69_2_; Column 'something69_2_' not found.
但是,something69_2_
不会出现在 SQL 查询中。这就像 Hibernate 生成了一个 SQL 查询并期望something69_2_
在结果中,但事实并非如此。
编辑 2:类似问题记录为未修复的Hibernate 错误 HHH-3035
编辑 3:这是一个记录在案的Hibernate 错误 HHH-3636,已修复但尚未包含在任何版本中。
编辑 4:我构建了 hibernate-core 3.3.2-SNAPSHOT,其中包括错误修复 HHH-3636,但它没有解决这个问题。
编辑 5:错误行为似乎是由LEFT JOIN FETCH
ManyToMany 或 OneToMany 关系上的多个触发的。一个会起作用,两个或三个会导致错误。
编辑 6:这是堆栈跟踪:
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
编辑 7:所有这些连接的原因是为了避免 Hibernate 执行 n+1 查询,请参阅Hibernate FAQ 关于如何在运行 Hibernate 查询时避免 n+1 SQL SELECT 查询?