I have three tables: Customer, CustomerSettings, and CustomerProfile. The latter two both have bi-directional relationships with Customer and share Customer's PK (via foreign key constraint).
Behavior I'm trying to achieve:
1)
Customer c = (Customer) session.load(Customer.class, "1");
//Expect: SELECT only Customer. Actually: as expected
2)
c.getCustomerProfile();
//Expect: issue one SELECT only from CustomerProfile. Actually: two selects issued: one for CustomerProfile, one for CustomerSettings. Why?
Problem:
when 2) is executed I see two SELECTs instead of one: for *both* CustomerProfile and CustomerSettings. Why? Note that if I comment out step 2), the hibernate correctly issues a single SELECT for Customer only.
I use instrumentation via cglib. Is my expected behavior achievable? If so, how?
thanks
-nikita
Hibernate version:
3.2.5.ga
Mapping documents:
Code:
<hibernate-mapping>
<class dynamic-update="true" table="customer" name="net.eviltwinstudios.common.beans.Customer" dynamic-insert="true">
<id name="id">
<generator class="assigned"/>
</id>
<version unsaved-value="null" name="hibernateVersion"/>
<property name="name"/>
<one-to-one name="customerProfile" lazy="no-proxy" cascade="all" fetch="select"/>
<one-to-one name="customerSettings" lazy="no-proxy" cascade="all" fetch="select"/>
<property name="creationDate"/>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class dynamic-update="true" table="customer_profile" name="net.eviltwinstudios.common.beans.CustomerProfile" dynamic-insert="true">
<id name="id">
<generator class="foreign">
<param name="property">customer</param>
</generator>
</id>
<version unsaved-value="null" name="hibernateVersion"/>
<one-to-one name="customer" constrained="true"/>
<property name="creationDate"/>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class dynamic-update="true" table="customer_settings" name="net.eviltwinstudios.common.beans.CustomerSettings" dynamic-insert="true">
<id name="id">
<generator class="foreign">
<param name="property">customer</param>
</generator>
</id>
<version unsaved-value="null" name="hibernateVersion"/>
<one-to-one name="customer" constrained="true"/>
<property name="creationDate"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
session.beginTransaction();
//read Customer only - only 1 row should be SELECT'ed
Customer c = (Customer) session.load(Customer.class, "1");
//read simple string property - NO add'l SELECTs
c.getName();
//EXPECT: select from customerProfile where id = 1;
//ACTUAL: select from customerProfile where id = 1; select from customerSettings where id = 1;
c.getCustomerProfile(); //SELECTS BOTH CustomerProfile anf CustomerSettings WHY????
session.getTransaction().commit();
Name and version of the database you are using:
mysql 5.1 INNODB
The generated SQL (show_sql=true):
Quote:
select customer0_.id as id14_0_, customer0_.hibernateVersion as hibernat2_14_0_, customer0_.name as name14_0_, customer0_.creationDate as creation4_14_0_ from customer customer0_ where customer0_.id='1'
select customerpr0_.id as id15_0_, customerpr0_.hibernateVersion as hibernat2_15_0_, customerpr0_.creationDate as creation3_15_0_ from customer_profile customerpr0_ where customerpr0_.id='1'
select customerse0_.id as id16_0_, customerse0_.hibernateVersion as hibernat2_16_0_, customerse0_.creationDate as creation3_16_0_ from customer_settings customerse0_ where customerse0_.id='1'