mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-16 16:15:06 +00:00
HHH-3229 : Added test cases for modifying an entity with multiple paths to associated entities
git-svn-id: https://svn.jboss.org/repos/hibernate/core/branches/Branch_3_2@14502 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
d83703123c
commit
e94b243e72
106
test/org/hibernate/test/cascade/A.java
Executable file
106
test/org/hibernate/test/cascade/A.java
Executable file
@ -0,0 +1,106 @@
|
||||
// $Id$
|
||||
|
||||
package org.hibernate.test.cascade;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:ovidiu@feodorov.com">Ovidiu Feodorov</a>
|
||||
*
|
||||
* Copyright 2008 Ovidiu Feodorov
|
||||
*
|
||||
*/
|
||||
public class A
|
||||
{
|
||||
// Constants -----------------------------------------------------------------------------------
|
||||
|
||||
// Static --------------------------------------------------------------------------------------
|
||||
|
||||
// Attributes ----------------------------------------------------------------------------------
|
||||
|
||||
private long id;
|
||||
|
||||
private String data;
|
||||
|
||||
// A 1 - * H
|
||||
private Set hs;
|
||||
|
||||
// A 1 - 1 G
|
||||
private G g;
|
||||
|
||||
|
||||
// Constructors --------------------------------------------------------------------------------
|
||||
|
||||
public A()
|
||||
{
|
||||
hs = new HashSet();
|
||||
}
|
||||
|
||||
public A(String data)
|
||||
{
|
||||
this();
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
// Public --------------------------------------------------------------------------------------
|
||||
|
||||
public long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setData(String data)
|
||||
{
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setHs(Set hs)
|
||||
{
|
||||
this.hs = hs;
|
||||
}
|
||||
|
||||
public Set getHs()
|
||||
{
|
||||
return hs;
|
||||
}
|
||||
|
||||
public void setG(G g)
|
||||
{
|
||||
this.g = g;
|
||||
}
|
||||
|
||||
public G getG()
|
||||
{
|
||||
return g;
|
||||
}
|
||||
|
||||
public void addH(H h)
|
||||
{
|
||||
hs.add(h);
|
||||
h.setA(this);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "A[" + id + ", " + data + "]";
|
||||
}
|
||||
|
||||
// Package protected ---------------------------------------------------------------------------
|
||||
|
||||
// Protected -----------------------------------------------------------------------------------
|
||||
|
||||
// Private -------------------------------------------------------------------------------------
|
||||
|
||||
// Inner classes -------------------------------------------------------------------------------
|
||||
}
|
@ -12,6 +12,7 @@ public static Test suite() {
|
||||
TestSuite suite = new TestSuite( "Cascade tests" );
|
||||
suite.addTest( BidirectionalOneToManyCascadeTest.suite() );
|
||||
suite.addTest( RefreshTest.suite() );
|
||||
suite.addTest( MultiPathCascadeTest.suite() );
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
95
test/org/hibernate/test/cascade/G.java
Executable file
95
test/org/hibernate/test/cascade/G.java
Executable file
@ -0,0 +1,95 @@
|
||||
package org.hibernate.test.cascade;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:ovidiu@feodorov.com">Ovidiu Feodorov</a>
|
||||
*
|
||||
* Copyright 2008 Ovidiu Feodorov
|
||||
*
|
||||
* @version <tt>$Revision$</tt>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
public class G
|
||||
{
|
||||
// Constants -----------------------------------------------------------------------------------
|
||||
|
||||
// Static --------------------------------------------------------------------------------------
|
||||
|
||||
// Attributes ----------------------------------------------------------------------------------
|
||||
|
||||
private long id;
|
||||
|
||||
private String data;
|
||||
|
||||
// A 1 <-> 1 G
|
||||
private A a;
|
||||
|
||||
// G * <-> * H
|
||||
private Set hs;
|
||||
|
||||
// Constructors --------------------------------------------------------------------------------
|
||||
|
||||
public G()
|
||||
{
|
||||
this(null);
|
||||
}
|
||||
|
||||
public G(String data)
|
||||
{
|
||||
this.data = data;
|
||||
hs = new HashSet();
|
||||
}
|
||||
|
||||
// Public --------------------------------------------------------------------------------------
|
||||
|
||||
public String getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(String data)
|
||||
{
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public A getA()
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
public void setA(A a)
|
||||
{
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
public Set getHs()
|
||||
{
|
||||
return hs;
|
||||
}
|
||||
|
||||
public void setHs(Set s)
|
||||
{
|
||||
hs = s;
|
||||
}
|
||||
|
||||
// Package protected ---------------------------------------------------------------------------
|
||||
|
||||
long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
// Protected -----------------------------------------------------------------------------------
|
||||
|
||||
// Private -------------------------------------------------------------------------------------
|
||||
|
||||
private void setId(long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
// Inner classes -------------------------------------------------------------------------------
|
||||
}
|
94
test/org/hibernate/test/cascade/H.java
Executable file
94
test/org/hibernate/test/cascade/H.java
Executable file
@ -0,0 +1,94 @@
|
||||
// $Id$
|
||||
|
||||
|
||||
package org.hibernate.test.cascade;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:ovidiu@feodorov.com">Ovidiu Feodorov</a>
|
||||
*
|
||||
* Copyright 2008 Ovidiu Feodorov
|
||||
*
|
||||
*/
|
||||
public class H
|
||||
{
|
||||
// Constants -----------------------------------------------------------------------------------
|
||||
|
||||
// Static --------------------------------------------------------------------------------------
|
||||
|
||||
// Attributes ----------------------------------------------------------------------------------
|
||||
|
||||
private long id;
|
||||
|
||||
private String data;
|
||||
|
||||
private A a;
|
||||
|
||||
// G * <-> * H
|
||||
private Set gs;
|
||||
|
||||
// Constructors --------------------------------------------------------------------------------
|
||||
|
||||
public H()
|
||||
{
|
||||
this(null);
|
||||
}
|
||||
|
||||
public H(String data)
|
||||
{
|
||||
this.data = data;
|
||||
gs = new HashSet();
|
||||
}
|
||||
|
||||
// Public --------------------------------------------------------------------------------------
|
||||
|
||||
public long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(String data)
|
||||
{
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public A getA()
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
public void setA(A a)
|
||||
{
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
public Set getGs()
|
||||
{
|
||||
return gs;
|
||||
}
|
||||
|
||||
public void setGs(Set gs)
|
||||
{
|
||||
this.gs = gs;
|
||||
}
|
||||
|
||||
// Package protected ---------------------------------------------------------------------------
|
||||
|
||||
// Protected -----------------------------------------------------------------------------------
|
||||
|
||||
// Private -------------------------------------------------------------------------------------
|
||||
|
||||
private void setId(long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
// Inner classes -------------------------------------------------------------------------------
|
||||
}
|
67
test/org/hibernate/test/cascade/MultiPathCascade.hbm.xml
Normal file
67
test/org/hibernate/test/cascade/MultiPathCascade.hbm.xml
Normal file
@ -0,0 +1,67 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
|
||||
|
||||
<hibernate-mapping package="org.hibernate.test.cascade">
|
||||
|
||||
<class name="A" table="HB_A">
|
||||
|
||||
<id name="id" type="long"><generator class="native"/></id>
|
||||
|
||||
<property name="data" type="string" not-null="true"/>
|
||||
|
||||
<!--
|
||||
Associations
|
||||
-->
|
||||
|
||||
<set name="hs" inverse="true" cascade="all">
|
||||
<key column="a_fk"/>
|
||||
<one-to-many class="H"/>
|
||||
</set>
|
||||
<one-to-one name="g" class="G" property-ref="a" cascade="all"/>
|
||||
|
||||
</class>
|
||||
|
||||
<class name="G" table="HB_G">
|
||||
|
||||
<id name="id" type="long"><generator class="native"/></id>
|
||||
|
||||
<property name="data" type="string" not-null="true"/>
|
||||
|
||||
<!--
|
||||
Associations
|
||||
-->
|
||||
|
||||
<set name="hs" inverse="true" table="HB_G_H" cascade="all">
|
||||
<key column="g_fk"/>
|
||||
<many-to-many class="H" column="h_fk"/>
|
||||
</set>
|
||||
|
||||
<many-to-one name="a"
|
||||
column="aId"
|
||||
unique="true"
|
||||
not-null="false"/>
|
||||
|
||||
</class>
|
||||
|
||||
<class name="H" table="HB_H">
|
||||
|
||||
<id name="id" type="long"><generator class="native"/></id>
|
||||
|
||||
<property name="data" type="string" not-null="true"/>
|
||||
|
||||
<!--
|
||||
Associations
|
||||
-->
|
||||
|
||||
<!-- *NOT* cascaded -->
|
||||
<set name="gs" table="HB_G_H">
|
||||
<key column="h_fk"/>
|
||||
<many-to-many class="G" column="g_fk"/>
|
||||
</set>
|
||||
|
||||
<many-to-one name="a" column="a_fk" class="A"/>
|
||||
|
||||
</class>
|
||||
|
||||
|
||||
</hibernate-mapping>
|
160
test/org/hibernate/test/cascade/MultiPathCascadeTest.java
Normal file
160
test/org/hibernate/test/cascade/MultiPathCascadeTest.java
Normal file
@ -0,0 +1,160 @@
|
||||
//$Id: $
|
||||
|
||||
package org.hibernate.test.cascade;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.junit.functional.FunctionalTestCase;
|
||||
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:ovidiu@feodorov.com">Ovidiu Feodorov</a>
|
||||
* @author Gail Badner
|
||||
*
|
||||
*/
|
||||
|
||||
public class MultiPathCascadeTest extends FunctionalTestCase {
|
||||
|
||||
public MultiPathCascadeTest(String name) {
|
||||
super( name );
|
||||
}
|
||||
|
||||
public String[] getMappings() {
|
||||
return new String[] {
|
||||
"cascade/MultiPathCascade.hbm.xml"
|
||||
};
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return new FunctionalTestClassTestSuite( MultiPathCascadeTest.class );
|
||||
}
|
||||
|
||||
public void testMultiPathMergeDetachedFailureExpected() throws Exception
|
||||
{
|
||||
// persist a simple A in the database
|
||||
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
A a = new A();
|
||||
a.setData("Anna");
|
||||
s.save(a);
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
// modify detached entity
|
||||
modifyEntity( a );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
s.merge(a);
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
verifyModifications( a.getId() );
|
||||
}
|
||||
|
||||
public void testMultiPathUpdateDetached() throws Exception
|
||||
{
|
||||
// persist a simple A in the database
|
||||
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
A a = new A();
|
||||
a.setData("Anna");
|
||||
s.save(a);
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
// modify detached entity
|
||||
modifyEntity( a );
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
s.update(a);
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
verifyModifications( a.getId() );
|
||||
}
|
||||
|
||||
public void testMultiPathGetAndModify() throws Exception
|
||||
{
|
||||
// persist a simple A in the database
|
||||
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
A a = new A();
|
||||
a.setData("Anna");
|
||||
s.save(a);
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
s.beginTransaction();
|
||||
// retrieve the previously saved instance from the database, and update it
|
||||
a = ( A ) s.get( A.class, new Long( a.getId() ) );
|
||||
modifyEntity( a );
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
|
||||
verifyModifications( a.getId() );
|
||||
}
|
||||
|
||||
private void modifyEntity(A a) {
|
||||
// create a *circular* graph in detached entity
|
||||
a.setData("Anthony");
|
||||
|
||||
G g = new G();
|
||||
g.setData("Giovanni");
|
||||
|
||||
H h = new H();
|
||||
h.setData("Hellen");
|
||||
|
||||
a.setG(g);
|
||||
g.setA(a);
|
||||
|
||||
a.getHs().add(h);
|
||||
h.setA(a);
|
||||
|
||||
g.getHs().add(h);
|
||||
h.getGs().add(g);
|
||||
}
|
||||
|
||||
private void verifyModifications(long aId) {
|
||||
Session s = openSession();
|
||||
s.beginTransaction();
|
||||
|
||||
// retrieve the A object and check it
|
||||
A a = ( A ) s.get( A.class, new Long( aId ) );
|
||||
assertEquals( aId, a.getId() );
|
||||
assertEquals( "Anthony", a.getData() );
|
||||
assertNotNull( a.getG() );
|
||||
assertNotNull( a.getHs() );
|
||||
assertEquals( 1, a.getHs().size() );
|
||||
|
||||
G gFromA = a.getG();
|
||||
H hFromA = ( H ) a.getHs().iterator().next();
|
||||
|
||||
// check the G object
|
||||
assertEquals( "Giovanni", gFromA.getData() );
|
||||
assertSame( a, gFromA.getA() );
|
||||
assertNotNull( gFromA.getHs() );
|
||||
assertEquals( a.getHs(), gFromA.getHs() );
|
||||
assertSame( hFromA, gFromA.getHs().iterator().next() );
|
||||
|
||||
// check the H object
|
||||
assertEquals( "Hellen", hFromA.getData() );
|
||||
assertSame( a, hFromA.getA() );
|
||||
assertNotNull( hFromA.getGs() );
|
||||
assertEquals( 1, hFromA.getGs().size() );
|
||||
assertSame( gFromA, hFromA.getGs().iterator().next() );
|
||||
|
||||
s.getTransaction().commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user