I'm using Hibernate 3.2.4 SP 1 and have the following mapping document:
Code:
<hibernate-mapping>
<class name="DataExchange" table="dataexchange">
<id name="id">
<generator class="identity"/>
</id>
<many-to-one name="user" column="USER_ID" class="User" not-null="true"/>
<set name="categories" table="DATAEXCHANGE_TO_CATEGORY" sort="natural">
<key column="DATAEXCHANGE_ID" not-null="true"/>
<many-to-many column="CATEGORY_ID" class="Category"/>
</set>
</class>
</hibernate-mapping>
Everything quite usual so far I think. Now the HQL:
Code:
select dataExchange from DataExchange as dataExchange
join fetch dataExchange.categories as category
where category in (:categories)
Works so far ... even changing it to
Code:
select dataExchange, category from DataExchange as dataExchange
join fetch dataExchange.categories as category
where category in (:categories)
(see select clause) still works. Hibernate creates the following SQL (IBM DB 2):
Code:
select dataexchan0_.id as id18_0_, category2_.id as id16_1_, category2_.id as id16_2_, [..]
from dataexchange dataexchan0_
inner join DATAEXCHANGE_TO_CATEGORY categories1_ on dataexchan0_.id=categories1_.DATAEXCHANGE_ID
inner join DATAEXCHANGE_CATEGORY category2_ on categories1_.CATEGORY_ID=category2_.id
where category2_.id in (? , ? , ? , ? , ?)
Now it gets interesting. Two ways to break Hibernate:
1. Changing the select clause from "dataExchange, category" to "category, dataExchange". The SQL select clause changes to
Code:
select category2_.id as id16_0_, dataexchan0_.id as id18_1_
Hibernate tries to access id18_0_ on the ResultSet though!
Code:
Hibernate operation: could not execute query; uncategorized SQLException for SQL [..]; SQL state [null]; error code [-99999]; Invalid argument: unknown column name id18_0_; nested exception is com.ibm.db2.jcc.c.SqlException: Invalid argument: unknown column name id18_0_
Caused by: com.ibm.db2.jcc.c.SqlException: Invalid argument: unknown column name id18_0_
at com.ibm.db2.jcc.c.m.a(m.java:1262)
at com.ibm.db2.jcc.c.rc.a(rc.java:1368)
at com.ibm.db2.jcc.c.rc.getLong(rc.java:1161)
at org.tranql.connector.jdbc.ResultSetHandle.getLong(ResultSetHandle.java:476)
at org.hibernate.type.LongType.get(LongType.java:28)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:163)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:154)
at org.hibernate.loader.Loader.getKeyFromResultSet(Loader.java:1097)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:565)
at org.hibernate.loader.Loader.doQuery(Loader.java:701)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.doList(Loader.java:2220)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
at org.hibernate.loader.Loader.list(Loader.java:2099)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:378)
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)
This means Hibernate tries to access a column by its alias name without having mapped that alias.
The
2. way to break is to add another join to the first (and working) HQL query:
Code:
select dataExchange, category from DataExchange as dataExchange
join fetch dataExchange.categories as category
join fetch dataExchange.user as user
where category in (:categories)
Generated SQL:
Code:
select dataexchan0_.id as id18_0_, category2_.id as id16_1_, category2_.id as id16_2_, user3_.id as id14_3_, [..]
from dataexchange dataexchan0_
inner join DATAEXCHANGE_TO_CATEGORY categories1_ on dataexchan0_.id=categories1_.DATAEXCHANGE_ID
inner join DATAEXCHANGE_CATEGORY category2_ on categories1_.CATEGORY_ID=category2_.id
inner join User user3_ on dataexchan0_.USER_ID=user3_.id
where category2_.id in (? , ? , ? , ? , ?)
Hibernate makes again stupid things by trying to access unmapped column alias id_14_2_:
Code:
org.springframework.jdbc.UncategorizedSQLException: Hibernate operation: could not execute query; uncategorized SQLException for SQL [..]; SQL state [null]; error code [-99999]; Invalid argument: unknown column name id14_2_; nested exception is com.ibm.db2.jcc.c.SqlException: Invalid argument: unknown column name id14_2_
Now I wonder where Hibernate goes wrong here. Is the HQL in any way incorrect and Hibernate's HQL parser just tell me? Or is there a bug somewhere deep in Hibernate?
For the moment I've worked around it by using the first HQL (with only "dataExchange" in select clause) and doing the rest in the application logic. It works at least.
Any ideas? Feel free to ask if you need more information.
Joerg