JPA / Hibernate查询中允许的连接数是否有限制?
从Hibernate doesn't automatically join开始,我必须在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.
我确实将Hibernate的方言设置为我的数据库实现,MySQL:
<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_
在结果中,而不是。{/ p>
编辑2:类似的问题记录为unfixed Hibernate bug HHH-3035
编辑3:这是一份记录在案的Hibernate bug HHH-3636,已经修复但尚未发布任何版本。
编辑4:我构建了hibernate-core 3.3.2-SNAPSHOT,其中包含错误修复HHH-3636,并没有解决这个问题。
编辑5:错误行为似乎是由ManyToMany或OneToMany关系上的多个LEFT JOIN FETCH
触发的。一个会工作,两个或三个导致错误。
编辑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 on How can I avoid n+1 SQL SELECT queries when running a Hibernate query?
答案 0 :(得分:2)
我曾经使用Hibernate达到MySQL 5.0 61表限制:
ERROR 1116 (HY000): Too many tables; MySQL can only use 61 tables in a join
答案 1 :(得分:2)
问题是你为什么要首先尝试进行如此复杂的查询?
你考虑过不同的方法吗? improving performance上的文档提出了一些建议。
答案 2 :(得分:1)
Hibernate代码中没有任何内容限制了连接数。这可能是方言中的错误,也可能是数据库引擎的限制。但我的钱是关于一个与连接数无关的错误!您是否尝试在交互式查询会话中直接运行SQL?
答案 3 :(得分:0)
您是否尝试使用实际的jdbc驱动程序执行?这可能是jdbc驱动程序的一个问题。
虽然从列的名称判断,但它正在寻找,我猜有一些修剪/构造名称出错了。绝对看起来更像是一个bug而非预期的限制。
答案 4 :(得分:0)
你是否将所有内部联接别名?并使用这些别名?当你尝试在SELECT
子句中使用隐式别名来做这样的事情时(非常简化的例子),我已经看到了Hibernate的一些非常奇怪的行为:
select p.address.state from person p
但如果您明确声明所有别名,它就可以正常工作。像这样:
select s from person p join p.address a join a.state s
......甚至是这个:
select s from person p join p.address.state s