//$Id: $
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
*/
package org.hibernate.test.cascade.circle;
import junit.framework.Test;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.junit.functional.FunctionalTestCase;
import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
/**
* The test case uses the following model:
*
* <- ->
* -- (N : 0,1) -- Tour
* | <- ->
* | -- (1 : N) -- (pickup) ----
* -> | | |
* Route -- (1 : N) - Node Transport
* | | <- -> | |
* | -- (1 : N) -- (delivery) -- |
* | |
* | -> -> |
* -------- (1 : N) ---- Vehicle--(1 : N)------------
*
* Arrows indicate the direction of cascade-merge.
*
* I believe it reproduces the following issue:
* http://opensource.atlassian.com/projects/hibernate/browse/HHH-3544
*
* @author Gail Badner (based on original model provided by Pavol Zibrita)
*/
public class CascadeMergeToChildBeforeParentTest extends FunctionalTestCase {
public CascadeMergeToChildBeforeParentTest(String string) {
super(string);
}
public String[] getMappings() {
return new String[] {
"cascade/circle/CascadeMergeToChildBeforeParent.hbm.xml"
};
}
@Override
public void configure(Configuration cfg) {
super.configure( cfg );
cfg.setProperty( Environment.CHECK_NULLABILITY, "true" );
}
public static Test suite() {
return new FunctionalTestClassTestSuite( CascadeMergeToChildBeforeParentTest.class );
}
protected void cleanupTest() {
Session s = openSession();
s.beginTransaction();
s.createQuery( "delete from Transport" );
s.createQuery( "delete from Tour" );
s.createQuery( "delete from Node" );
s.createQuery( "delete from Route" );
s.createQuery( "delete from Vehicle" );
}
public void testMerge()
{
Session s = openSession();
s.beginTransaction();
Route route = new Route();
route.setName("routeA");
s.save( route );
s.getTransaction().commit();
s.close();
s = openSession();
s.beginTransaction();
route = (Route) s.get(Route.class, new Long(1));
route.setTransientField(new String("sfnaouisrbn"));
Tour tour = new Tour();
tour.setName("tourB");
Node pickupNode = new Node();
pickupNode.setName("pickupNodeB");
Node deliveryNode = new Node();
deliveryNode.setName("deliveryNodeB");
pickupNode.setRoute(route);
pickupNode.setTour(tour);
pickupNode.setTransientField("pickup node aaaaaaaaaaa");
deliveryNode.setRoute(route);
deliveryNode.setTour(tour);
deliveryNode.setTransientField("delivery node aaaaaaaaa");
tour.getNodes().add(pickupNode);
tour.getNodes().add(deliveryNode);
route.getNodes().add(pickupNode);
route.getNodes().add(deliveryNode);
Route mergedRoute = (Route) s.merge(route);
s.getTransaction().commit();
s.close();
}
// This test fails because the merge algorithm tries to save a
// transient child (transport) before cascade-merge gets its
// transient parent (vehicle); merge does not cascade from the
// child to the parent.
public void testMergeTransientChildBeforeTransientParent()
{
Session s = openSession();
s.beginTransaction();
Route route = new Route();
route.setName("routeA");
s.save( route );
s.getTransaction().commit();
s.close();
s = openSession();
s.beginTransaction();
route = (Route) s.get(Route.class, new Long(1));
route.setTransientField(new String("sfnaouisrbn"));
Tour tour = new Tour();
tour.setName("tourB");
Transport transport = new Transport();
transport.setName("transportB");
Node pickupNode = new Node();
pickupNode.setName("pickupNodeB");
Node deliveryNode = new Node();
deliveryNode.setName("deliveryNodeB");
Vehicle vehicle = new Vehicle();
vehicle.setName("vehicleB");
pickupNode.setRoute(route);
pickupNode.setTour(tour);
pickupNode.getPickupTransports().add(transport);
pickupNode.setTransientField("pickup node aaaaaaaaaaa");
deliveryNode.setRoute(route);
deliveryNode.setTour(tour);
deliveryNode.getDeliveryTransports().add(transport);
deliveryNode.setTransientField("delivery node aaaaaaaaa");
tour.getNodes().add(pickupNode);
tour.getNodes().add(deliveryNode);
route.getNodes().add(pickupNode);
route.getNodes().add(deliveryNode);
route.getVehicles().add(vehicle);
transport.setPickupNode(pickupNode);
transport.setDeliveryNode(deliveryNode);
transport.setVehicle( vehicle );
transport.setTransientField("aaaaaaaaaaaaaa");
vehicle.getTransports().add(transport);
vehicle.setTransientField( "anewvalue" );
vehicle.setRoute( route );
Route mergedRoute = (Route) s.merge(route);
s.getTransaction().commit();
s.close();
}
public void testMergeData3Nodes()
{
Session s = openSession();
s.beginTransaction();
Route route = new Route();
route.setName("routeA");
s.save( route );
s.getTransaction().commit();
s.close();
s = openSession();
s.beginTransaction();
route = (Route) s.get(Route.class, new Long(1));
route.setTransientField(new String("sfnaouisrbn"));
Tour tour = new Tour();
tour.setName("tourB");
Transport transport1 = new Transport();
transport1.setName("TRANSPORT1");
Transport transport2 = new Transport();
transport2.setName("TRANSPORT2");
Node node1 = new Node();
node1.setName("NODE1");
Node node2 = new Node();
node2.setName("NODE2");
Node node3 = new Node();
node3.setName("NODE3");
Vehicle vehicle = new Vehicle();
vehicle.setName("vehicleB");
node1.setRoute(route);
node1.setTour(tour);
node1.getPickupTransports().add(transport1);
node1.setTransientField("node 1");
node2.setRoute(route);
node2.setTour(tour);
node2.getDeliveryTransports().add(transport1);
node2.getPickupTransports().add(transport2);
node2.setTransientField("node 2");
node3.setRoute(route);
node3.setTour(tour);
node3.getDeliveryTransports().add(transport2);
node3.setTransientField("node 3");
tour.getNodes().add(node1);
tour.getNodes().add(node2);
tour.getNodes().add(node3);
route.getNodes().add(node1);
route.getNodes().add(node2);
route.getNodes().add(node3);
route.getVehicles().add(vehicle);
transport1.setPickupNode(node1);
transport1.setDeliveryNode(node2);
transport1.setVehicle( vehicle );
transport1.setTransientField("aaaaaaaaaaaaaa");
transport2.setPickupNode(node2);
transport2.setDeliveryNode(node3);
transport2.setVehicle( vehicle );
transport2.setTransientField("bbbbbbbbbbbbb");
vehicle.getTransports().add(transport1);
vehicle.getTransports().add(transport2);
vehicle.setTransientField( "anewvalue" );
vehicle.setRoute( route );
Route mergedRoute = (Route) s.merge(route);
s.getTransaction().commit();
s.close();
}
}