Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp
I have three objects: User, Permission and History. User has bidirectional one-to-one association with Permission, Permission has bidirectional one-to-many association with History.
Hibernate version: 3.2.5.ga
Mapping documents:
User.hbm.xml
Quote:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="gor.domain.User"
table="USER"
proxy="gor.domain.User">
<id name="id" column="ID" type="integer" unsaved-value="null">
<generator class="identity"/>
</id>
<version name="version" column="TX_VERSION"/>
<property name="name" column="NAME"/>
<property name="email" column="EMAIL"/>
<property name="phone" column="PHONE"/>
<component name="address">
<property name="address" column="ADDRESS"/>
<property name="city" column="CITY"/>
</component>
<one-to-one name="permission" class="gor.domain.Permission" cascade="all"/>
<bag name="preferences" cascade="all">
<key column="USER_ID"/>
<one-to-many class="gor.domain.Preference"/>
</bag>
</class>
</hibernate-mapping>
Permission.hbm.xmlQuote:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="gor.domain.Permission"
table="PERMISSION"
proxy="gor.domain.Permission">
<id name="id" column="ID" type="integer" unsaved-value="null">
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>
<version name="version" column="TX_VERSION"/>
<property name="operation" column="OPERATION"/>
<property name="object" column="OBJECT"/>
<one-to-one name="user" class="gor.domain.User"/>
<bag name="historyRecords" cascade="all" lazy="false">
<key column="PERMISSION_ID"/>
<one-to-many class="gor.domain.History"/>
</bag>
</class>
</hibernate-mapping>
History.hbm.xmlQuote:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="gor.domain.History"
table="HISTORY"
proxy="gor.domain.History">
<id name="id" column="ID" type="integer" unsaved-value="null">
<generator class="identity"/>
</id>
<version name="version" column="TX_VERSION"/>
<property name="event" column="EVENT"/>
<many-to-one name="permission" column="PERMISSION_ID" class="gor.domain.Permission"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
hbmResult = HbmSessionFactory.getSession().createQuery(
"select u.name, p From User u inner join u.permission p where u.id=1 order by u.id"
).list();
Name and version of the database you are using:
HSQLDB 1.8.0.7
The generated SQL (show_sql=true):
Hibernate:
select user0_.NAME as col_0_0_, permission1_.ID as col_1_0_, permission1_.ID as ID1_, permission1_.TX_VERSION as TX2_1_, permission1_.OPERATION as OPERATION1_, permission1_.OBJECT as OBJECT1_ from USER user0_ inner join PERMISSION permission1_ on user0_.ID=permission1_.ID where user0_.ID=1 order by user0_.ID
Hibernate:
select user0_.ID as ID0_2_, user0_.TX_VERSION as TX2_0_2_, user0_.NAME as NAME0_2_, user0_.EMAIL as EMAIL0_2_, user0_.PHONE as PHONE0_2_, user0_.ADDRESS as ADDRESS0_2_, user0_.CITY as CITY0_2_, permission1_.ID as ID1_0_, permission1_.TX_VERSION as TX2_1_0_, permission1_.OPERATION as OPERATION1_0_, permission1_.OBJECT as OBJECT1_0_, user2_.ID as ID0_1_, user2_.TX_VERSION as TX2_0_1_, user2_.NAME as NAME0_1_, user2_.EMAIL as EMAIL0_1_, user2_.PHONE as PHONE0_1_, user2_.ADDRESS as ADDRESS0_1_, user2_.CITY as CITY0_1_ from USER user0_ left outer join PERMISSION permission1_ on user0_.ID=permission1_.ID left outer join USER user2_ on permission1_.ID=user2_.ID where user0_.ID=?
Hibernate:
select historyrec0_.PERMISSION_ID as PERMISSION4_1_, historyrec0_.ID as ID1_, historyrec0_.ID as ID2_0_, historyrec0_.TX_VERSION as TX2_2_0_, historyrec0_.EVENT as EVENT2_0_, historyrec0_.PERMISSION_ID as PERMISSION4_2_0_ from HISTORY historyrec0_ where historyrec0_.PERMISSION_ID=?
The questions are:
1) Hibernate returns list of size=1 with array of objects with length=2: correct User's name, but null as the Permission. Associated permission exists in DB. Why it's null?
2) Why Hibernate executes second query (selected bold above) with two outer joins?
At the same time if i slightly change HQL query to this:
hbmResult = HbmSessionFactory.getSession().createQuery(
"select u, p From User u inner join u.permission p where u.id=1 order by u.id"
).list();
Hibernate returns User and corresponding Permission and
doesn't execute second query:
The generated SQL (show_sql=true):
Hibernate: select user0_.ID as ID0_0_, permission1_.ID as ID1_1_, user0_.TX_VERSION as TX2_0_0_, user0_.NAME as NAME0_0_, user0_.EMAIL as EMAIL0_0_, user0_.PHONE as PHONE0_0_, user0_.ADDRESS as ADDRESS0_0_, user0_.CITY as CITY0_0_, permission1_.TX_VERSION as TX2_1_1_, permission1_.OPERATION as OPERATION1_1_, permission1_.OBJECT as OBJECT1_1_ from USER user0_ inner join PERMISSION permission1_ on user0_.ID=permission1_.ID where user0_.ID=1 order by user0_.ID
Hibernate: select historyrec0_.PERMISSION_ID as PERMISSION4_1_, historyrec0_.ID as ID1_, historyrec0_.ID as ID2_0_, historyrec0_.TX_VERSION as TX2_2_0_, historyrec0_.EVENT as EVENT2_0_, historyrec0_.PERMISSION_ID as PERMISSION4_2_0_ from HISTORY historyrec0_ where historyrec0_.PERMISSION_ID=?
Could someone explain me the difference between these two cases?
Problems with Session and transaction handling?
Read this:
http://hibernate.org/42.html