Hibernate version: 3.1
Name and version of the database you are using: HSQLDB
Explanation:
I am trying to learn about Hibernates handling of proxies, especially in Polymorphic relationships: I currently have the following class hierarchy:
Event
Person
-Developer
I hope I have mapped a many-to-many relation between Event and Person for the Event property "participants" and the Person property "events" and a second one-to-one mapping between Event and Person for the "organizer" property of Event.
Mapping documents:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Event" table="EVENT">
<id name="id" column="EVENT_ID">
<generator class="increment" />
</id>
<property name="date" type="timestamp" column="EVENT_DATE" />
<property name="title" />
<set fetch="select" name="participants" table="PERSON_EVENT" inverse="true">
<key column="EVENT_ID" />
<many-to-many column="PERSON_ID"
class="sics.hibernate.test.Person" />
</set>
<one-to-one name="organizer" class="Person"
fetch="select" lazy="proxy"/>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Person" table="PERSON">
<id name="id" column="PERSON_ID">
<generator class="increment" />
</id>
<discriminator column="SUBCLASS" type="string" />
<property name="age" />
<property name="firstname" />
<property name="lastname" />
<set name="events" table="PERSON_EVENT" fetch="select" lazy="true">
<key column="PERSON_ID" />
<many-to-many column="EVENT_ID" class="Event" />
</set>
<set name="emailAddresses" table="PERSON_EMAIL_ADDR">
<key column="PERSON_ID" />
<element type="string" column="EMAIL_ADDR" />
</set>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<subclass name="Developer"
extends="Person" discriminator-value="1">
<property name="project" />
</subclass>
</hibernate-mapping>
Code:
Code:
// Create a developer, and an Event
EventManager mgr = new EventManager();
Long devId = mgr.createAndStoreDeveloper("Foo", "Bar", 32, "Hibernate");
Long eventId = mgr.createAndStoreEvent("First Event", new java.util.Date());
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
// Read the Event
Event event = (Event) session.get(Event.class, eventId);
// Read the Developer
Developer dev = (Developer)session.get(Developer.class, devId);
// Set the Developer and the organizer of the Event
event.setOrganizer(dev);
tx.commit();
HibernateUtil.closeSession();
// Start new session
session = HibernateUtil.currentSession();
tx = session.beginTransaction();
System.out.println("New Session");
event = (Event) session.load(Event.class, eventId);
System.out.println("Event Access");
event.getDate();
tx.commit();
HibernateUtil.closeSession();
The generated SQL :Code:
Hibernate: insert into PERSON (age, firstname, lastname, project, SUBCLASS, PERSON_ID) values (?, ?, ?, ?, '1', ?)
Hibernate: insert into EVENT (EVENT_DATE, title, EVENT_ID) values (?, ?, ?)
Hibernate: select event0_.EVENT_ID as EVENT1_0_, event0_.EVENT_DATE as EVENT2_0_0_, event0_.title as title0_0_ from EVENT event0_ where event0_.EVENT_ID=?
Hibernate: select person0_.PERSON_ID as PERSON1_0_, person0_.age as age2_0_, person0_.firstname as firstname2_0_, person0_.lastname as lastname2_0_, person0_.project as project2_0_, person0_.SUBCLASS as SUBCLASS0_ from PERSON person0_ where person0_.PERSON_ID=?
New Session
Event Access
Hibernate: select event0_.EVENT_ID as EVENT1_0_, event0_.EVENT_DATE as EVENT2_0_0_, event0_.title as title0_0_ from EVENT event0_ where event0_.EVENT_ID=?
Hibernate: select person0_.PERSON_ID as PERSON1_0_, person0_.age as age2_0_, person0_.firstname as firstname2_0_, person0_.lastname as lastname2_0_, person0_.project as project2_0_, person0_.SUBCLASS as SUBCLASS0_ from PERSON person0_ where person0_.PERSON_ID=?
Question ...Why does the organizer get read when the Event object's date property is accessed (The last "Hibernate:" statement) ? I would not expect this SQL to be triggered until code like the following was executed:
Code:
event.getOrganizer().getFirstname();