/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.cascade.circle;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
/**
* The test case uses the following model:
*
* <- ->
* -- (N : 0,1) -- Tour
* | <- ->
* | -- (1 : N) -- (pickup) ----
* <- -> | | |
* Route -- (1 : N) -- Node Transport
* | <- -> |
* -- (1 : N) -- (delivery) --
*
* Arrows indicate the direction of cascade-merge, cascade-save, cascade-refresh and cascade-save-or-update
*
* It reproduces the following issues:
* https://hibernate.atlassian.net/browse/HHH-9512
* <p/>
* This tests that cascades are done properly from each entity.
*
* @author Alex Belyaev (based on code by Pavol Zibrita and Gail Badner)
*/
public class CascadeManagedAndTransientTest extends BaseCoreFunctionalTestCase {
@Override
public String[] getMappings() {
return new String[] {
"cascade/circle/CascadeManagedAndTransient.hbm.xml"
};
}
@Override
public void configure(Configuration cfg) {
super.configure( cfg );
cfg.setProperty( Environment.CHECK_NULLABILITY, "true" );
}
@Override
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" );
}
private void checkNewVehicle(Vehicle newVehicle) {
assertEquals("Bus", newVehicle.getName());
assertEquals(1, newVehicle.getTransports().size());
Transport t = (Transport) newVehicle.getTransports().iterator().next();
assertEquals("Transport 2 -> 3", t.getName());
assertEquals("Node 2", t.getPickupNode().getName());
assertEquals("Node 3", t.getDeliveryNode().getName());
}
@Test
public void testAttachedChildInMerge() {
fillInitialData();
Session s = openSession();
s.beginTransaction();
Route route = (Route) s.createQuery("FROM Route WHERE name = :name").setString("name", "Route 1").uniqueResult();
Node n2 = (Node) s.createQuery("FROM Node WHERE name = :name").setString("name", "Node 2").uniqueResult();
Node n3 = (Node) s.createQuery("FROM Node WHERE name = :name").setString("name", "Node 3").uniqueResult();
Vehicle vehicle = new Vehicle();
vehicle.setName("Bus");
vehicle.setRoute(route);
Transport $2to3 = new Transport();
$2to3.setName("Transport 2 -> 3");
$2to3.setPickupNode(n2); n2.getPickupTransports().add($2to3);
$2to3.setDeliveryNode(n3); n3.getDeliveryTransports().add($2to3);
$2to3.setVehicle(vehicle);
vehicle.setTransports(new HashSet<Transport>(Arrays.asList($2to3)));
// Try to save graph of transient entities (vehicle, transport) which contains attached entities (node2, node3)
Vehicle managedVehicle = (Vehicle) s.merge(vehicle);
checkNewVehicle(managedVehicle);
s.flush();
s.clear();
assertEquals(3, s.createQuery("FROM Transport").list().size());
assertEquals(2, s.createQuery("FROM Vehicle").list().size());
assertEquals(4, s.createQuery("FROM Node").list().size());
Vehicle newVehicle = (Vehicle) s.createQuery("FROM Vehicle WHERE name = :name").setParameter("name", "Bus").uniqueResult();
checkNewVehicle(newVehicle);
s.getTransaction().commit();
s.close();
}
private void fillInitialData() {
Tour tour = new Tour();
tour.setName("Tour 1");
Route route = new Route();
route.setName("Route 1");
ArrayList<Node> nodes = new ArrayList<Node>();
for (int i = 0; i < 4; i++) {
Node n = new Node();
n.setName("Node " + i);
n.setTour(tour);
n.setRoute(route);
nodes.add(n);
}
tour.setNodes(new HashSet<Node>(nodes));
route.setNodes(new HashSet<Node>(Arrays.asList(nodes.get(0), nodes.get(1), nodes.get(2))));
Vehicle vehicle = new Vehicle();
vehicle.setName("Car");
route.setVehicles(new HashSet<Vehicle>(Arrays.asList(vehicle)));
vehicle.setRoute(route);
Transport $0to1 = new Transport();
$0to1.setName("Transport 0 -> 1");
$0to1.setPickupNode(nodes.get(0));
$0to1.setDeliveryNode(nodes.get(1));
$0to1.setVehicle(vehicle);
Transport $1to2 = new Transport();
$1to2.setName("Transport 1 -> 2");
$1to2.setPickupNode(nodes.get(1));
$1to2.setDeliveryNode(nodes.get(2));
$1to2.setVehicle(vehicle);
vehicle.setTransports(new HashSet<Transport>(Arrays.asList($0to1, $1to2)));
Session s = openSession();
s.beginTransaction();
s.persist(tour);
s.getTransaction().commit();
s.close();
}
}