HHH-2542 : Merge non-null component in a child persisted with a null component and added test for optional components
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@12937 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
d40aa403b2
commit
ce0cbf1f18
|
@ -553,7 +553,7 @@ public final class TypeFactory {
|
||||||
AbstractComponentType componentType = ( AbstractComponentType ) types[i];
|
AbstractComponentType componentType = ( AbstractComponentType ) types[i];
|
||||||
Type[] subtypes = componentType.getSubtypes();
|
Type[] subtypes = componentType.getSubtypes();
|
||||||
Object[] origComponentValues = original[i] == null ? new Object[subtypes.length] : componentType.getPropertyValues( original[i], session );
|
Object[] origComponentValues = original[i] == null ? new Object[subtypes.length] : componentType.getPropertyValues( original[i], session );
|
||||||
Object[] targetComponentValues = componentType.getPropertyValues( target[i], session );
|
Object[] targetComponentValues = target[i] == null ? new Object[subtypes.length] : componentType.getPropertyValues( target[i], session );
|
||||||
replaceAssociations( origComponentValues, targetComponentValues, subtypes, session, null, copyCache, foreignKeyDirection );
|
replaceAssociations( origComponentValues, targetComponentValues, subtypes, session, null, copyCache, foreignKeyDirection );
|
||||||
copied[i] = target[i];
|
copied[i] = target[i];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//$Id: ComponentTest.java 11349 2007-03-28 15:37:21Z steve.ebersole@jboss.com $
|
//$Id: ComponentTest.java 11346 2007-03-26 17:24:58Z steve.ebersole@jboss.com $
|
||||||
package org.hibernate.test.component.basic;
|
package org.hibernate.test.component.basic;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -9,6 +9,7 @@ import junit.framework.Test;
|
||||||
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.Transaction;
|
import org.hibernate.Transaction;
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.cfg.Mappings;
|
import org.hibernate.cfg.Mappings;
|
||||||
|
@ -34,6 +35,10 @@ public class ComponentTest extends FunctionalTestCase {
|
||||||
return new String[] { "component/basic/User.hbm.xml" };
|
return new String[] { "component/basic/User.hbm.xml" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Test suite() {
|
||||||
|
return new FunctionalTestClassTestSuite( ComponentTest.class );
|
||||||
|
}
|
||||||
|
|
||||||
public void configure(Configuration cfg) {
|
public void configure(Configuration cfg) {
|
||||||
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
|
cfg.setProperty( Environment.GENERATE_STATISTICS, "true" );
|
||||||
}
|
}
|
||||||
|
@ -62,10 +67,6 @@ public class ComponentTest extends FunctionalTestCase {
|
||||||
f.setFormula( yearFunction.render( args, null ) );
|
f.setFormula( yearFunction.render( args, null ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Test suite() {
|
|
||||||
return new FunctionalTestClassTestSuite(ComponentTest.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testUpdateFalse() {
|
public void testUpdateFalse() {
|
||||||
getSessions().getStatistics().clear();
|
getSessions().getStatistics().clear();
|
||||||
|
@ -190,5 +191,131 @@ public class ComponentTest extends FunctionalTestCase {
|
||||||
s.close();
|
s.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testMergeComponent() {
|
||||||
|
Session s = openSession();
|
||||||
|
Transaction t = s.beginTransaction();
|
||||||
|
Employee emp = new Employee();
|
||||||
|
emp.setHireDate( new Date() );
|
||||||
|
emp.setPerson( new Person() );
|
||||||
|
emp.getPerson().setName( "steve" );
|
||||||
|
emp.getPerson().setDob( new Date() );
|
||||||
|
s.persist( emp );
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
t = s.beginTransaction();
|
||||||
|
emp = (Employee)s.get( Employee.class, emp.getId() );
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
assertNull(emp.getOptionalComponent());
|
||||||
|
emp.setOptionalComponent( new OptionalComponent() );
|
||||||
|
emp.getOptionalComponent().setValue1( "emp-value1" );
|
||||||
|
emp.getOptionalComponent().setValue2( "emp-value2" );
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
t = s.beginTransaction();
|
||||||
|
emp = (Employee)s.merge( emp );
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
t = s.beginTransaction();
|
||||||
|
emp = (Employee)s.get( Employee.class, emp.getId() );
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
assertEquals("emp-value1", emp.getOptionalComponent().getValue1());
|
||||||
|
assertEquals("emp-value2", emp.getOptionalComponent().getValue2());
|
||||||
|
emp.getOptionalComponent().setValue1( null );
|
||||||
|
emp.getOptionalComponent().setValue2( null );
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
t = s.beginTransaction();
|
||||||
|
emp = (Employee)s.merge( emp );
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
t = s.beginTransaction();
|
||||||
|
emp = (Employee)s.get( Employee.class, emp.getId() );
|
||||||
|
Hibernate.initialize(emp.getDirectReports());
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
assertNull(emp.getOptionalComponent());
|
||||||
|
|
||||||
|
Employee emp1 = new Employee();
|
||||||
|
emp1.setHireDate( new Date() );
|
||||||
|
emp1.setPerson( new Person() );
|
||||||
|
emp1.getPerson().setName( "bozo" );
|
||||||
|
emp1.getPerson().setDob( new Date() );
|
||||||
|
emp.getDirectReports().add( emp1 );
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
t = s.beginTransaction();
|
||||||
|
emp = (Employee)s.merge( emp );
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
t = s.beginTransaction();
|
||||||
|
emp = (Employee)s.get( Employee.class, emp.getId() );
|
||||||
|
Hibernate.initialize(emp.getDirectReports());
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
assertEquals(1, emp.getDirectReports().size());
|
||||||
|
emp1 = (Employee)emp.getDirectReports().iterator().next();
|
||||||
|
assertNull( emp1.getOptionalComponent() );
|
||||||
|
emp1.setOptionalComponent( new OptionalComponent() );
|
||||||
|
emp1.getOptionalComponent().setValue1( "emp1-value1" );
|
||||||
|
emp1.getOptionalComponent().setValue2( "emp1-value2" );
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
t = s.beginTransaction();
|
||||||
|
emp = (Employee)s.merge( emp );
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
t = s.beginTransaction();
|
||||||
|
emp = (Employee)s.get( Employee.class, emp.getId() );
|
||||||
|
Hibernate.initialize(emp.getDirectReports());
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
assertEquals(1, emp.getDirectReports().size());
|
||||||
|
emp1 = (Employee)emp.getDirectReports().iterator().next();
|
||||||
|
assertEquals( "emp1-value1", emp1.getOptionalComponent().getValue1());
|
||||||
|
assertEquals( "emp1-value2", emp1.getOptionalComponent().getValue2());
|
||||||
|
emp1.getOptionalComponent().setValue1( null );
|
||||||
|
emp1.getOptionalComponent().setValue2( null );
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
t = s.beginTransaction();
|
||||||
|
emp = (Employee)s.merge( emp );
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
t = s.beginTransaction();
|
||||||
|
emp = (Employee)s.get( Employee.class, emp.getId() );
|
||||||
|
Hibernate.initialize(emp.getDirectReports());
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
assertEquals(1, emp.getDirectReports().size());
|
||||||
|
emp1 = (Employee)emp.getDirectReports().iterator().next();
|
||||||
|
assertNull(emp1.getOptionalComponent());
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
t = s.beginTransaction();
|
||||||
|
s.delete( emp );
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package org.hibernate.test.component.basic;
|
package org.hibernate.test.component.basic;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* todo: describe Employee
|
* todo: describe Employee
|
||||||
|
@ -11,6 +13,8 @@ public class Employee {
|
||||||
private Long id;
|
private Long id;
|
||||||
private Person person;
|
private Person person;
|
||||||
private Date hireDate;
|
private Date hireDate;
|
||||||
|
private OptionalComponent optionalComponent;
|
||||||
|
private Set directReports = new HashSet();
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
|
@ -35,4 +39,20 @@ public class Employee {
|
||||||
public void setHireDate(Date hireDate) {
|
public void setHireDate(Date hireDate) {
|
||||||
this.hireDate = hireDate;
|
this.hireDate = hireDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OptionalComponent getOptionalComponent() {
|
||||||
|
return optionalComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOptionalComponent(OptionalComponent optionalComponent) {
|
||||||
|
this.optionalComponent = optionalComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set getDirectReports() {
|
||||||
|
return directReports;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDirectReports(Set directReports) {
|
||||||
|
this.directReports = directReports;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
//$Id: $
|
||||||
|
package org.hibernate.test.component.basic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class OptionalComponent {
|
||||||
|
private String value1;
|
||||||
|
private String value2;
|
||||||
|
|
||||||
|
public String getValue1() {
|
||||||
|
return value1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue1(String value1) {
|
||||||
|
this.value1 = value1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue2() {
|
||||||
|
return value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue2(String value2) {
|
||||||
|
this.value2 = value2;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!DOCTYPE hibernate-mapping PUBLIC
|
<!DOCTYPE hibernate-mapping PUBLIC
|
||||||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||||
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<hibernate-mapping package="org.hibernate.test.component.basic">
|
<hibernate-mapping package="org.hibernate.test.component.basic">
|
||||||
|
|
||||||
<class name="User" table="T_USER">
|
<class name="User" table="T_USER">
|
||||||
<id name="userName"/>
|
<id name="userName"/>
|
||||||
<timestamp name="lastModified"/>
|
<timestamp name="lastModified"/>
|
||||||
|
@ -19,9 +19,9 @@
|
||||||
<property name="address"/>
|
<property name="address"/>
|
||||||
<property name="previousAddress" insert="false"/>
|
<property name="previousAddress" insert="false"/>
|
||||||
<property name="yob" formula="year(dob)"/>
|
<property name="yob" formula="year(dob)"/>
|
||||||
<property name="currentAddress"
|
<property name="currentAddress"
|
||||||
column="address"
|
column="address"
|
||||||
insert="false"
|
insert="false"
|
||||||
update="false"/>
|
update="false"/>
|
||||||
</component>
|
</component>
|
||||||
</class>
|
</class>
|
||||||
|
@ -35,8 +35,16 @@
|
||||||
<property name="name" update="false" not-null="true"/>
|
<property name="name" update="false" not-null="true"/>
|
||||||
<property name="dob" update="false" not-null="true"/>
|
<property name="dob" update="false" not-null="true"/>
|
||||||
</component>
|
</component>
|
||||||
|
<component name="optionalComponent">
|
||||||
|
<property name="value1" not-null="false"/>
|
||||||
|
<property name="value2" not-null="false"/>
|
||||||
|
</component>
|
||||||
|
<set name="directReports" cascade="all-delete-orphan,merge" lazy="true">
|
||||||
|
<key column="PARENT_ID" />
|
||||||
|
<one-to-many class="Employee"/>
|
||||||
|
</set>
|
||||||
</class>
|
</class>
|
||||||
|
|
||||||
<query name="userNameIn"><![CDATA[from User where person.name in (:nameList) or userName in (:nameList)]]></query>
|
<query name="userNameIn"><![CDATA[from User where person.name in (:nameList) or userName in (:nameList)]]></query>
|
||||||
|
|
||||||
</hibernate-mapping>
|
</hibernate-mapping>
|
||||||
|
|
Loading…
Reference in New Issue