Есть ли ограничение на количество соединений, разрешенных в запросе 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.
У меня есть диалект 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_ будет в результатах, но это не так.
Изменить 2: Аналогичная проблема, задокументированная как нефиксированная ошибка гибернации HHH-3035
Изменить 3: Это задокументированный Ошибка гибернации 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 о том, как избежать n + 1 запросов SQL SELECT при выполнении запроса Hibernate?
Предложение where не имеет значения. Я пробовал 1) предложение no where и 2) простое предложение where (WHERE id = 1).
Почему бы тогда не использовать выборочную выборку вместо присоединения?




В коде Hibernate нет ничего, что ограничивало бы количество соединений. Это может быть ошибка диалекта или ограничение механизма базы данных. Но мои деньги на ошибку, не связанную с количеством присоединений! Вы пробовали запускать SQL непосредственно в сеансе интерактивного запроса?
SQL-запрос работает нормально. Проблема в том, что Hibernate пытается прочитать несуществующее поле результата.
Однажды я достиг предела таблицы MySQL 5.0 61 с Hibernate:
ERROR 1116 (HY000): Too many tables; MySQL can only use 61 tables in a join
Вы пытались выполнить с фактическим используемым драйвером jdbc? Возможно, это проблема драйвера jdbc.
Хотя, судя по названию столбца, он ищет, я предполагаю, что некоторая обрезка / построение имен идет не так. Определенно больше похоже на ошибку, чем на предполагаемый предел.
Вопрос в том, почему вы вообще пытаетесь составить такой сложный запрос?
Вы рассматривали разные подходы? В документации по повышение производительности есть несколько предложений.
Без объединений Hibernate будет делать n + 1 запросов, что приведет к очень низкой производительности. См. hibernate.org/118.html#A23
Вы используете псевдоним все своих внутренних соединений? И используя эти псевдонимы? Я видел действительно странное поведение Hibernate, когда вы пытались использовать неявное псевдонимание в предложении SELECT, чтобы делать такие вещи (чрезвычайно упрощенный пример):
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
Просто любопытно, насколько сложно предложение where в вашем запросе JPA?