If I fetch an object in one session and close that session before initializing any relationships, then attach that object to a new session, Hibernate is immediately doing one fetch for each to-one relationship. Uninitialized to-many relationships do not get automatically fetched. This leads to n+1 select problems when attaching objects. In my case, I don't even need the unitialized to-one relationships, but they are fetched anyway. Is there any reason this has to be?
Hibernate version:
Hibernate3.0.5 and 3.1
Mapping documents:
Code:
<class name="test.cascades.Manuscript" table="MANUSCRIPT">
<id name="id"/>
<version name = "versionNumber" column="VERSION_NUMBER" type="long"/>
<many-to-one name="correspondence" cascade="all" lazy="no-proxy" column="CORR_ID"/>
<many-to-one name="publishData" cascade="all" lazy="proxy" column="PUBLISH_DATA_ID"/>
<set name="manContactInfos" cascade="all, delete-orphan" inverse="true">
<key column="MANUSCRIPT_ID"/>
<one-to-many class="test.cascades.ManuscriptContactInfo"/>
</set>
</class>
Code between sessionFactory.openSession() and session.close():Code:
public void testAttachWithNonInitialized() {
Manuscript m = new Manuscript(new Long(1));
m.setAccode("AA1001");
PublishData pubData = new PublishData(new Long(1));
m.setPublishData(pubData);
ManuscriptContactInfo manContactInfo = new ManuscriptContactInfo();
manContactInfo.setAddress("test");
manContactInfo.setManuscript(m);
m.getManContactInfos().add(manContactInfo);
Session s = openSession();
Transaction tx = s.beginTransaction();
s.save(m);
tx.commit();
s.close();
s = openSession();
m = (Manuscript)s.get(Manuscript.class, m.getId());
assertTrue(s.contains(m));
assertFalse(Hibernate.isInitialized(m.getPublishData()));
assertFalse(Hibernate.isInitialized(m.getManContactInfos()));
s.close();
s = openSession();
System.out.println("\nattaching\n\n");
s.lock(m, LockMode.NONE);
assertTrue(s.contains(m));
assertTrue(Hibernate.isInitialized(m.getPublishData()));
assertFalse(Hibernate.isInitialized(m.getManContactInfos()));
}
Debug level Hibernate log excerpt:
Hibernate: select publishdat_.id, publishdat_.pubDate as pubDate1_ from PUBLISH_DATA publishdat_ where publishdat_.id=?
Hibernate: insert into PUBLISH_DATA (pubDate, id) values (?, ?)
Hibernate: insert into MANUSCRIPT (VERSION_NUMBER, CORR_ID, PUBLISH_DATA_ID, id) values (?, ?, ?, ?)
Hibernate: insert into MANUSCRIPT_CONTACT_INFO (ADDRESS, MANUSCRIPT_ID, ID) values (?, ?, null)
Hibernate: call identity()
Hibernate: select manuscript0_.id as id0_0_, manuscript0_.VERSION_NUMBER as VERSION2_0_0_, manuscript0_.CORR_ID as CORR3_0_0_, manuscript0_.PUBLISH_DATA_ID as PUBLISH4_0_0_ from MANUSCRIPT manuscript0_ where manuscript0_.id=?
attaching
Hibernate: select publishdat0_.id as id1_0_, publishdat0_.pubDate as pubDate1_0_ from PUBLISH_DATA publishdat0_ where publishdat0_.id=?