|
From: <hib...@li...> - 2006-07-28 10:05:51
|
Author: ste...@jb...
Date: 2006-07-26 13:16:46 -0400 (Wed, 26 Jul 2006)
New Revision: 10171
Added:
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/join/User.java
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/join/JoinTest.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/join/Person.hbm.xml
Log:
ported fix for HHH-1713 to 3.2 branch
Modified: branches/Branch_3_2/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- branches/Branch_3_2/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-07-26 17:10:17 UTC (rev 10170)
+++ branches/Branch_3_2/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-07-26 17:16:46 UTC (rev 10171)
@@ -1961,6 +1961,7 @@
final boolean hasDeferred = rootPersister.hasSequentialSelect();
PreparedStatement sequentialSelect = null;
ResultSet sequentialResultSet = null;
+ boolean sequentialSelectEmpty = false;
try {
if ( hasDeferred ) {
@@ -1970,7 +1971,30 @@
sequentialSelect = session.getBatcher().prepareSelectStatement( sql );
rootPersister.getIdentifierType().nullSafeSet( sequentialSelect, id, 1, session );
sequentialResultSet = sequentialSelect.executeQuery();
- sequentialResultSet.next();
+ if ( !sequentialResultSet.next() ) {
+ // TODO: Deal with the "optional" attribute in the <join> mapping;
+ // this code assumes that optional defaults to "true" because it
+ // doesn't actually seem to work in the fetch="join" code
+ //
+ // Note that actual proper handling of optional-ality here is actually
+ // more involved than this patch assumes. Remember that we might have
+ // multiple <join/> mappings associated with a single entity. Really
+ // a couple of things need to happen to properly handle optional here:
+ // 1) First and foremost, when handling multiple <join/>s, we really
+ // should be using the entity root table as the driving table;
+ // another option here would be to choose some non-optional joined
+ // table to use as the driving table. In all likelihood, just using
+ // the root table is much simplier
+ // 2) Need to add the FK columns corresponding to each joined table
+ // to the generated select list; these would then be used when
+ // iterating the result set to determine whether all non-optional
+ // data is present
+ // My initial thoughts on the best way to deal with this would be
+ // to introduce a new SequentialSelect abstraction that actually gets
+ // generated in the persisters (ok, SingleTable...) and utilized here.
+ // It would encapsulated all this required optional-ality checking...
+ sequentialSelectEmpty = true;
+ }
}
}
@@ -1988,11 +2012,14 @@
//decide which ResultSet to get the property value from:
final boolean propertyIsDeferred = hasDeferred &&
rootPersister.isSubclassPropertyDeferred( propNames[i], propSubclassNames[i] );
- final ResultSet propertyResultSet = propertyIsDeferred ? sequentialResultSet : rs;
- final String[] cols = propertyIsDeferred ?
- propertyColumnAliases[i] : suffixedPropertyColumns[i];
-
- values[i] = types[i].hydrate( propertyResultSet, cols, session, object );
+ if ( propertyIsDeferred && sequentialSelectEmpty ) {
+ values[i] = null;
+ }
+ else {
+ final ResultSet propertyResultSet = propertyIsDeferred ? sequentialResultSet : rs;
+ final String[] cols = propertyIsDeferred ? propertyColumnAliases[i] : suffixedPropertyColumns[i];
+ values[i] = types[i].hydrate( propertyResultSet, cols, session, object );
+ }
}
else {
values[i] = LazyPropertyInitializer.UNFETCHED_PROPERTY;
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/join/JoinTest.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/join/JoinTest.java 2006-07-26 17:10:17 UTC (rev 10170)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/join/JoinTest.java 2006-07-26 17:16:46 UTC (rev 10171)
@@ -90,6 +90,39 @@
s.close();
}
+ public void testSequentialSelectsOptionalData() throws Exception {
+ Session s = openSession();
+ Transaction t = s.beginTransaction();
+
+ User jesus = new User();
+ jesus.setName("Jesus Olvera y Martinez");
+ jesus.setSex('M');
+
+ s.save(jesus);
+
+ assertEquals( s.createQuery("from java.io.Serializable").list().size(), 0 );
+
+ assertEquals( s.createQuery("from Person").list().size(), 1 );
+ assertEquals( s.createQuery("from Person p where p.class is null").list().size(), 0 );
+ assertEquals( s.createQuery("from Person p where p.class = User").list().size(), 1 );
+ assertTrue(s.createQuery("from User u").list().size()==1);
+ s.clear();
+
+ // Remove the optional row from the join table and requery the User obj
+ s.connection().prepareStatement("delete from t_user").execute();
+ s.clear();
+
+ jesus = (User) s.get( Person.class, new Long( jesus.getId() ) );
+ s.clear();
+
+ // Cleanup the test data
+ s.delete(jesus);
+
+ assertTrue( s.createQuery("from Person").list().isEmpty() );
+ t.commit();
+ s.close();
+ }
+
protected String[] getMappings() {
return new String[] { "join/Person.hbm.xml" };
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/join/Person.hbm.xml
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/join/Person.hbm.xml 2006-07-26 17:10:17 UTC (rev 10170)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/join/Person.hbm.xml 2006-07-26 17:16:46 UTC (rev 10171)
@@ -23,53 +23,36 @@
-->
-<hibernate-mapping
- package="org.hibernate.test.join"
- default-access="field">
-
- <class name="Person"
- table="person"
- lazy="true"
- discriminator-value="null">
-
- <id name="id"
- column="person_id"
- unsaved-value="0">
+<hibernate-mapping package="org.hibernate.test.join" default-access="field">
+
+ <class name="Person" table="person" lazy="true" discriminator-value="null">
+
+ <id name="id" column="person_id" unsaved-value="0">
<generator class="native"/>
</id>
-
- <discriminator column="person_type"
- type="string"
- length="1"
- not-null="false"
- force="true"/> <!--unnecessary, in case we had other unknown discriminator values -->
-
- <property name="name"
- not-null="true"
- length="80"/>
- <property name="sex"
- not-null="true"
- update="false"/>
-
+
+ <!-- force is unnecessary, in case we had other unknown discriminator values -->
+ <discriminator column="person_type" type="string" length="1" not-null="false" force="true"/>
+
+ <property name="name" not-null="true" length="80"/>
+ <property name="sex" not-null="true" update="false"/>
+
<join table="address">
<key column="address_id"/>
<property name="address"/>
<property name="zip"/>
<property name="country"/>
</join>
-
+
<subclass name="Employee" lazy="true" discriminator-value="E">
<join table="employee" fetch="select">
<key column="person_id"/>
- <property name="title"
- not-null="true"
- length="20"/>
- <property name="salary"
- length="0"/>
+ <property name="title" not-null="true" length="20"/>
+ <property name="salary" length="0"/>
<many-to-one name="manager"/>
</join>
</subclass>
-
+
<subclass name="Customer" lazy="true" discriminator-value="C">
<join table="customer" fetch="select">
<key column="person_id"/>
@@ -77,8 +60,19 @@
<many-to-one name="salesperson"/>
</join>
</subclass>
-
+
+ <subclass name="User" lazy="true" discriminator-value="U">
+ <join table="t_user" fetch="select" optional="true">
+ <key column="person_id"/>
+ <property name="login" column="u_login"/>
+ </join>
+ <join table="t_silly" fetch="select" optional="true" >
+ <key column="person_id"/>
+ <property name="silly"/>
+ </join>
+ </subclass>
+
</class>
-
+
</hibernate-mapping>
Added: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/join/User.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/join/User.java 2006-07-26 17:10:17 UTC (rev 10170)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/join/User.java 2006-07-26 17:16:46 UTC (rev 10171)
@@ -0,0 +1,23 @@
+//$Id$
+package org.hibernate.test.join;
+
+/**
+ * @author Mike Dillon
+ */
+public class User extends Person {
+ private String login;
+ private String silly;
+
+ /**
+ * @return Returns the login.
+ */
+ public String getLogin() {
+ return login;
+ }
+ /**
+ * @param login The login to set.
+ */
+ public void setLogin(String login) {
+ this.login = login;
+ }
+}
|