JPA / Hibernate最大连接数?

时间:2009-01-21 22:22:43

标签: java hibernate jpa join

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?

5 个答案:

答案 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