/******************************************************************************* * Copyright (c) 2005, 2015 SAP. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * SAP - initial API and implementation ******************************************************************************/ package org.eclipse.persistence.testing.tests.wdf.jpa1.relation; import static junit.framework.Assert.assertTrue; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Set; import javax.persistence.Cache; import javax.persistence.EntityManager; import org.eclipse.persistence.testing.framework.wdf.Bugzilla; import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment; import org.eclipse.persistence.testing.framework.wdf.ToBeInvestigated; import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Bicycle; import org.eclipse.persistence.testing.models.wdf.jpa1.employee.CostCenter; import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Cubicle; import org.eclipse.persistence.testing.models.wdf.jpa1.employee.CubiclePrimaryKeyClass; import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Employee; import org.eclipse.persistence.testing.models.wdf.jpa1.employee.MotorVehicle; import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Project; import org.eclipse.persistence.testing.models.wdf.jpa1.employee.TravelProfile; import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Vehicle; import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base; import org.junit.Test; /** * Testing relations in combination with object cache. Test cases generated by all-pairs testing tool: <li>ToManyFK, eager, * owning side right, cacheable both: testCostCenterEmployee</li> <li>ToOneFK, lazy, owning side left, cacheable right: * testMotorVehicleEmployee</li> <li>ToOneFK, eager, owning side right, cacheable both: testCubicleEmployee</li> <li> * ToManyJoinTable, eager, owning side left, cacheable right: testBicycleEmployee</li> <li>ToManyJoinTable, lazy, owning side * left, cacheable both: testEmployeeProject</li> <li>ToManyFK, lazy, owning side right, cacheable right: n.a.</li> <li> * ToManyJoinTable, lazy, owning side right, cacheable right: testTravelProfileVehicle</li> * * * * <li>ToManyJoinTable, lazy, owning side right, cacheable both: testProjectEmployee</li> <li>ToManyJoinTable, lazy, owning side * left, cacheable left: testEmployeePatent</li> <li>ToOneFK, eager, owning side left, cacheable left: testEmployeeTravelProfile * </li> <li>ToManyFK, eager, owning side right, cacheable right</li> </ul> */ public class TestRelationshipsWithCache extends JPA1Base { /** * Test case: CostCenter.employees * <p> * Relationship mapping: ToManyFK, FetchType: eager, owning side: right, cacheable: both */ @Test @Bugzilla(bugid=309681) public void testCostCenterEmployee() { final JPAEnvironment env = getEnvironment(); final EntityManager em = env.getEntityManager(); final Cache cache = em.getEntityManagerFactory().getCache(); int costCenterId = 1; CostCenter costCenter = new CostCenter(1, "lotsOfMoney"); int employeeId1 = 1; int employeeId2 = 2; Employee employee1 = new Employee(employeeId1, "very", "expensive", null); Employee employee2 = new Employee(employeeId2, "even", "moreExpensive", null); costCenter.addEmployee(employee1); costCenter.addEmployee(employee2); employee1.setCostCenter(costCenter); employee2.setCostCenter(costCenter); try { env.beginTransaction(em); em.persist(costCenter); em.persist(employee1); em.persist(employee2); env.commitTransactionAndClear(em); em.find(CostCenter.class, costCenterId); // eager loading of Employees assertTrue(cache.contains(CostCenter.class, costCenterId)); assertTrue(cache.contains(Employee.class, employeeId1)); assertTrue(cache.contains(Employee.class, employeeId2)); env.beginTransaction(em); costCenter = em.find(CostCenter.class, costCenterId); employee1 = em.find(Employee.class, employeeId1); employee2 = em.find(Employee.class, employeeId2); List<Employee> foundEmployees = costCenter.getEmployees(); assertTrue(foundEmployees != null); assertTrue("wrong number of riders: " + foundEmployees.size(), foundEmployees.size() == 2); if (foundEmployees.get(0).getId() == employeeId1) { assertTrue("wrong rider: " + foundEmployees.get(1).getId(), foundEmployees.get(1).getId() == employeeId2); } else { assertTrue("wrong rider: " + foundEmployees.get(0).getId(), foundEmployees.get(0).getId() == employeeId2); assertTrue("wrong rider: " + foundEmployees.get(1).getId(), foundEmployees.get(1).getId() == employeeId1); } CostCenter costCenter1 = employee1.getCostCenter(); CostCenter costCenter2 = employee2.getCostCenter(); assertTrue(costCenter1 != null); assertTrue(costCenter1.getId() == costCenterId); assertTrue(costCenter2 != null); assertTrue(costCenter2.getId() == costCenterId); costCenter.setEmployees(null); employee1.setCostCenter(null); employee2.setCostCenter(null); env.commitTransactionAndClear(em); assertTrue(!cache.contains(CostCenter.class, costCenterId)); assertTrue(!cache.contains(Employee.class, employeeId1)); assertTrue(!cache.contains(Employee.class, employeeId2)); costCenter = em.find(CostCenter.class, costCenterId); employee1 = em.find(Employee.class, employeeId1); employee2 = em.find(Employee.class, employeeId2); assertTrue(costCenter.getEmployees().size() == 0); assertTrue(employee1.getCostCenter() == null); assertTrue(employee2.getCostCenter() == null); } finally { closeEntityManager(em); } } /** * Test case: MotorVehicle.driver * <p> * Relationship mapping: ToOneFK, FetchType: lazy, owning side: left, cacheable: right */ @Test @Bugzilla(bugid=309681) public void testMotorVehicleEmployee() { final JPAEnvironment env = getEnvironment(); final EntityManager em = env.getEntityManager(); final Cache cache = em.getEntityManagerFactory().getCache(); final boolean isLazyToOneEnabled = false; MotorVehicle motorVehicle = new MotorVehicle(); int employeeId = 11; Employee employee = new Employee(employeeId, "first", "driver", null); motorVehicle.setDriver(employee); employee.setMotorVehicle(motorVehicle); try { env.beginTransaction(em); em.persist(motorVehicle); em.persist(employee); env.commitTransactionAndClear(em); Short motorVehicleId = motorVehicle.getId(); em.find(MotorVehicle.class, motorVehicleId); if (isLazyToOneEnabled) { assertTrue(!cache.contains(Employee.class, employeeId)); employee = em.find(Employee.class, employeeId); // assertTrue(employee instanceof LazilyLoadable); FIXME // assertTrue( ((LazilyLoadable) employee)._isPending() ); FIXME } else { assertTrue(cache.contains(Employee.class, employeeId)); } env.beginTransaction(em); motorVehicle = em.find(MotorVehicle.class, motorVehicleId); employee = em.find(Employee.class, employeeId); assertTrue(employeeId == motorVehicle.getDriver().getId()); assertTrue(motorVehicleId.equals(employee.getMotorVehicle().getId())); assertTrue(employee == motorVehicle.getDriver()); motorVehicle.setDriver(null); employee.setMotorVehicle(null); env.commitTransactionAndClear(em); assertTrue(!cache.contains(Employee.class, employeeId)); motorVehicle = em.find(MotorVehicle.class, motorVehicleId); employee = em.find(Employee.class, employeeId); assertTrue(motorVehicle.getDriver() == null); assertTrue(employee.getMotorVehicle() == null); } finally { closeEntityManager(em); } } /** * Test case: Employee.cubicle * <p> * Relationship mapping: ToOneFK, FetchType: eager, owning side: right, cacheable: both */ @Test @Bugzilla(bugid=309681) public void testCubicleEmployee() { final JPAEnvironment env = getEnvironment(); final EntityManager em = env.getEntityManager(); final Cache cache = em.getEntityManagerFactory().getCache(); int employeeId = 21; Employee employee = new Employee(employeeId, "first", "last", null); CubiclePrimaryKeyClass cubicleId = new CubiclePrimaryKeyClass(1, 2); Cubicle cubicle = new Cubicle(cubicleId, "red", employee); employee.setCubicle(cubicle); try { env.beginTransaction(em); em.persist(employee); em.persist(cubicle); env.commitTransactionAndClear(em); em.find(Cubicle.class, cubicleId); assertTrue(cache.contains(Cubicle.class, cubicleId)); assertTrue(cache.contains(Employee.class, employeeId)); env.beginTransaction(em); cubicle = em.find(Cubicle.class, cubicleId); employee = em.find(Employee.class, employeeId); assertTrue("cubicle has wrong employee: " + cubicle.getEmployee().getId(), employeeId == cubicle.getEmployee() .getId()); assertTrue("employee has wrong cubicle: " + employee.getCubicle().getId(), cubicleId.equals(employee.getCubicle() .getId())); cubicle.setEmployee(null); employee.setCubicle(null); env.commitTransactionAndClear(em); assertTrue(!cache.contains(Cubicle.class, cubicleId)); assertTrue(!cache.contains(Employee.class, employeeId)); cubicle = em.find(Cubicle.class, cubicleId); employee = em.find(Employee.class, employeeId); assertTrue(cubicle.getEmployee() == null); assertTrue(employee.getCubicle() == null); } finally { closeEntityManager(em); } } /** * Test case: Bicycle.employees * <p> * Relationship mapping: ToManyJoinTable, FetchType: eager, owning side: left, cacheable: right */ @Test @Bugzilla(bugid=309681) public void testBicycleEmployee() { final JPAEnvironment env = getEnvironment(); final EntityManager em = env.getEntityManager(); final Cache cache = em.getEntityManagerFactory().getCache(); Bicycle bicycle = new Bicycle(); int employeeId1 = 31; int employeeId2 = 32; Employee employee1 = new Employee(employeeId1, "good", "rider1", null); Employee employee2 = new Employee(employeeId2, "bad", "rider2", null); employee1.addBicycle(bicycle); // maintains also bicycle.riders relationship employee2.addBicycle(bicycle); try { env.beginTransaction(em); em.persist(bicycle); em.persist(employee1); em.persist(employee2); env.commitTransactionAndClear(em); Short bicycleId = bicycle.getId(); em.find(Bicycle.class, bicycleId); // eager loading of Employees assertTrue(cache.contains(Employee.class, employeeId1)); assertTrue(cache.contains(Employee.class, employeeId2)); env.beginTransaction(em); bicycle = em.find(Bicycle.class, bicycleId); employee1 = em.find(Employee.class, employeeId1); employee2 = em.find(Employee.class, employeeId2); Collection<Employee> foundRiders = bicycle.getRiders(); assertTrue(foundRiders != null); assertTrue("wrong number of riders: " + foundRiders.size(), foundRiders.size() == 2); Employee[] ridersArray = foundRiders.toArray(new Employee[2]); if (ridersArray[0].getId() == employeeId1) { assertTrue("wrong rider: " + ridersArray[1].getId(), ridersArray[1].getId() == employeeId2); } else { assertTrue("wrong rider: " + ridersArray[0].getId(), ridersArray[0].getId() == employeeId2); assertTrue("wrong rider: " + ridersArray[1].getId(), ridersArray[1].getId() == employeeId1); } Set<Bicycle> bicycles1 = employee1.getBicycles(); Set<Bicycle> bicycles2 = employee2.getBicycles(); assertTrue(bicycles1 != null); assertTrue(bicycles2 != null); assertTrue(bicycles1.size() == 1); assertTrue(bicycles2.size() == 1); assertTrue(bicycleId.equals(bicycles1.toArray(new Bicycle[1])[0].getId())); assertTrue(bicycleId.equals(bicycles2.toArray(new Bicycle[1])[0].getId())); bicycle.setRiders(null); employee1.setBicycles(null); employee2.setBicycles(null); env.commitTransactionAndClear(em); assertTrue(!cache.contains(Employee.class, employeeId1)); assertTrue(!cache.contains(Employee.class, employeeId2)); bicycle = em.find(Bicycle.class, bicycleId); employee1 = em.find(Employee.class, employeeId1); employee2 = em.find(Employee.class, employeeId2); assertTrue(bicycle.getRiders().size() == 0); assertTrue(employee1.getBicycles().size() == 0); assertTrue(employee2.getBicycles().size() == 0); } finally { closeEntityManager(em); } } /** * Test case: Employee.projects * <p> * Relationship mapping: ToManyJoinTable, FetchType: lazy, owning side: left, cacheable: both */ @SuppressWarnings("unchecked") @Test @Bugzilla(bugid=309681) public void testEmployeeProject() { final JPAEnvironment env = getEnvironment(); final EntityManager em = env.getEntityManager(); final Cache cache = em.getEntityManagerFactory().getCache(); int employeeId = 41; Employee employee = new Employee(employeeId, "aaa", "member", null); Project project1 = new Project("evaluation"); Project project2 = new Project("demotivation"); project1.addEmployee(employee); // maintains also employee.projects relationship project2.addEmployee(employee); try { env.beginTransaction(em); em.persist(employee); em.persist(project1); em.persist(project2); env.commitTransactionAndClear(em); Integer projectId1 = project1.getId(); Integer projectId2 = project2.getId(); env.beginTransaction(em); employee = em.find(Employee.class, employeeId); assertTrue(cache.contains(Employee.class, employeeId)); assertTrue(!cache.contains(Project.class, projectId1)); // lazy loading of projects assertTrue(!cache.contains(Project.class, projectId2)); employee.getProjects().size(); assertTrue(cache.contains(Project.class, projectId1)); assertTrue(cache.contains(Project.class, projectId2)); project1 = em.find(Project.class, projectId1); project2 = em.find(Project.class, projectId2); Set<Project> foundProjects = employee.getProjects(); assertTrue(foundProjects != null); assertTrue("wrong number of projects: " + foundProjects.size(), foundProjects.size() == 2); Project[] projArray = foundProjects.toArray(new Project[2]); if (projArray[0].getId().equals(projectId1)) { assertTrue("wrong project: " + projArray[1].getId(), projArray[1].getId().equals(projectId2)); } else { assertTrue("wrong project: " + projArray[0].getId(), projArray[0].getId().equals(projectId2)); assertTrue("wrong project: " + projArray[1].getId(), projArray[1].getId().equals(projectId1)); } Set<Employee> employees1 = project1.getEmployees(); Set<Employee> employees2 = project2.getEmployees(); assertTrue(employees1 != null); assertTrue(employees2 != null); assertTrue(employees1.size() == 1); assertTrue(employees2.size() == 1); assertTrue(employees1.toArray(new Employee[1])[0].getId() == employeeId); assertTrue(employees2.toArray(new Employee[1])[0].getId() == employeeId); employee.setProjects(null); project1.setEmployees(null); project2.setEmployees(null); env.commitTransactionAndClear(em); assertTrue(!cache.contains(Employee.class, employeeId)); assertTrue(!cache.contains(Project.class, projectId1)); assertTrue(!cache.contains(Project.class, projectId2)); employee = em.find(Employee.class, employeeId); project1 = em.find(Project.class, projectId1); project2 = em.find(Project.class, projectId2); assertTrue(employee.getProjects().size() == 0); assertTrue(project1.getEmployees().size() == 0); assertTrue(project2.getEmployees().size() == 0); } finally { closeEntityManager(em); } } /** * Test case: TravelProfile.vehicles * <p> * Relationship mapping: ToManyJoinTable, FetchType: lazy, owning side: right, cacheable: right */ @SuppressWarnings("unchecked") @Test @ToBeInvestigated public void testTravelProfileVehicle() { // TODO remove final JPAEnvironment env = getEnvironment(); final EntityManager em = env.getEntityManager(); final Cache cache = em.getEntityManagerFactory().getCache(); byte[] travelProfileId = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; TravelProfile travelProfile = new TravelProfile(travelProfileId, true, "neverComeBack"); Vehicle vehicle1 = new Vehicle(); Vehicle vehicle2 = new Vehicle(); vehicle1.addProfile(travelProfile); // maintains also travelProfile.vehicles relationship vehicle2.addProfile(travelProfile); try { env.beginTransaction(em); em.persist(travelProfile); em.persist(vehicle1); em.persist(vehicle2); env.commitTransactionAndClear(em); Short vehicleId1 = vehicle1.getId(); Short vehicleId2 = vehicle2.getId(); env.beginTransaction(em); travelProfile = em.find(TravelProfile.class, travelProfileId); assertTrue(!cache.contains(Vehicle.class, vehicleId1)); // lazy loading of vehicles assertTrue(!cache.contains(Vehicle.class, vehicleId2)); travelProfile.getVehicles().size(); assertTrue(cache.contains(Vehicle.class, vehicleId1)); assertTrue(cache.contains(Vehicle.class, vehicleId2)); vehicle1 = em.find(Vehicle.class, vehicleId1); vehicle2 = em.find(Vehicle.class, vehicleId2); Set<Vehicle> foundVehicles = travelProfile.getVehicles(); assertTrue(foundVehicles != null); assertTrue("wrong number of vehicles: " + foundVehicles.size(), foundVehicles.size() == 2); Vehicle[] vehicleArray = foundVehicles.toArray(new Vehicle[2]); if (vehicleArray[0].getId().equals(vehicleId1)) { assertTrue("wrong vehicle: " + vehicleArray[1].getId(), vehicleArray[1].getId().equals(vehicleId2)); } else { assertTrue("wrong vehicle: " + vehicleArray[0].getId(), vehicleArray[0].getId().equals(vehicleId2)); assertTrue("wrong vehicle: " + vehicleArray[1].getId(), vehicleArray[1].getId().equals(vehicleId1)); } Set<TravelProfile> travelProfiles1 = vehicle1.getProfiles(); Set<TravelProfile> travelProfiles2 = vehicle2.getProfiles(); assertTrue(travelProfiles1 != null); assertTrue(travelProfiles2 != null); assertTrue(travelProfiles1.size() == 1); assertTrue(travelProfiles2.size() == 1); assertTrue(Arrays.equals(travelProfiles1.toArray(new TravelProfile[1])[0].getGuid(), travelProfileId)); assertTrue(Arrays.equals(travelProfiles2.toArray(new TravelProfile[1])[0].getGuid(), travelProfileId)); travelProfile.setVehicles(null); vehicle1.setProfiles(null); vehicle2.setProfiles(null); env.commitTransactionAndClear(em); assertTrue(!cache.contains(Vehicle.class, vehicleId1)); assertTrue(!cache.contains(Vehicle.class, vehicleId2)); travelProfile = em.find(TravelProfile.class, travelProfileId); vehicle1 = em.find(Vehicle.class, vehicleId1); vehicle2 = em.find(Vehicle.class, vehicleId2); assertTrue(travelProfile.getVehicles().size() == 0); assertTrue(vehicle1.getProfiles().size() == 0); assertTrue(vehicle2.getProfiles().size() == 0); } finally { closeEntityManager(em); } } @Test /** * just for the case that all other methods are skipped */ public void dummyTestMethod() { return; } }