package org.springmodules.prevayler; import java.util.List; import org.springframework.test.AbstractDependencyInjectionSpringContextTests; import org.springmodules.prevayler.callback.PrevaylerCallback; import org.springmodules.prevayler.test.domain.Employee; import org.springmodules.prevayler.test.domain.EmployeeImpl; import org.springmodules.prevayler.test.domain.Manager; import org.springmodules.prevayler.test.domain.ManagerImpl; import org.springmodules.prevayler.test.domain.Office; import org.springmodules.prevayler.test.domain.OfficeImpl; /** * @author Sergio Bossa */ public class PrevaylerTemplateTest extends AbstractDependencyInjectionSpringContextTests { private PrevaylerTemplate template; public PrevaylerTemplateTest(String testName) { super(testName); this.setAutowireMode(AUTOWIRE_BY_NAME); } protected void onTearDown() throws Exception { try { this.template.delete(Employee.class); this.template.delete(Office.class); } catch (Exception ex) { ex.printStackTrace(); } } public void testObjectReferenceIntegrity() { // Create an employee, assign it an office and save: EmployeeImpl emp1 = new EmployeeImpl("a1"); OfficeImpl o1 = new OfficeImpl("o1", "Office 1"); emp1.setOffice(o1); this.template.save(emp1); // Verify: o1 = (OfficeImpl) emp1.getOffice(); assertNotNull(emp1.getId()); assertNotNull(o1.getId()); // Change the office name and DIRECTLY update it: o1.setName("New name"); this.template.update(o1); // If we directly get the office, we see its name has been changed: o1 = (OfficeImpl) this.template.get(Office.class, o1.getId()); assertEquals("New name", o1.getName()); // If we get the office from the employee, the name is changed too: emp1 = (EmployeeImpl) this.template.get(Employee.class, emp1.getId()); OfficeImpl o2 = (OfficeImpl) emp1.getOffice(); assertNotNull("Value: " + o2.getName(), o2.getName()); // What's most important, the office directly retrieved from the template, // and the one retrieved from the employee, are the same: assertSame(o1, o2); } public void testSimpleSave() { EmployeeImpl emp = new EmployeeImpl("a1"); // Id null before adding: assertNull(emp.getId()); this.template.save(emp); // Id not null after adding: assertNotNull(emp.getId()); } public void testCascadeSave() { // Create the manager: ManagerImpl man1 = new ManagerImpl("m1"); // Create an employee and add it to the manager: EmployeeImpl emp1 = new EmployeeImpl("a1"); man1.addManagedEmployee(emp1); // Save the manager and the employee by cascade: this.template.save(man1); // The employee saved by cascade has a not null id: assertNotNull(emp1.getId()); // Verify object identities: EmployeeImpl empA = (EmployeeImpl) this.template.get(Employee.class, ((EmployeeImpl) man1.getManagedEmployees().iterator().next()).getId()); ManagerImpl manA = (ManagerImpl) this.template.get(Manager.class, man1.getId()); EmployeeImpl empB = (EmployeeImpl) manA.getManagedEmployees().iterator().next(); // The new employee, get from the manager, is not the same as the old one: assertNotSame(emp1, empA); // But the two employees got from the prevalent system, one by id, one from the manager, are the same: assertSame(empA, empB); } public void testUpdate() { EmployeeImpl emp = new EmployeeImpl("a1"); // Add an employee: this.template.save(emp); // Firstname is null: assertNull(emp.getFirstname()); // Set firstname: emp.setFirstname("Sergio"); // Update the employee: this.template.update(emp); // Read and verify: emp = (EmployeeImpl) this.template.get(emp.getClass(), emp.getId()); assertEquals("Sergio", emp.getFirstname()); } public void testCascadeUpdate() { // Create and save the manager: ManagerImpl man1 = new ManagerImpl("m1"); this.template.save(man1); // Create an employee and add it to the manager: EmployeeImpl emp1 = new EmployeeImpl("a1"); man1.addManagedEmployee(emp1); // Update the manager: this.template.update(man1); // Get the employee from the manager and change employee firstname: emp1 = (EmployeeImpl) man1.getManagedEmployees().iterator().next(); emp1.setFirstname("Sergio"); // Update the manager and the employee by cascade: this.template.update(man1); // Verify: emp1 = (EmployeeImpl) this.template.get(Employee.class, emp1.getId()); assertEquals("Sergio", emp1.getFirstname()); } public void testDeleteByEntity() { EmployeeImpl emp = new EmployeeImpl("a1"); // Add an employee: this.template.save(emp); // Delete it: this.template.delete(emp); // Try to get it by id and verify null is returned: emp = (EmployeeImpl) this.template.get(emp.getClass(), emp.getId()); assertNull(emp); } public void testDeleteByEntityClass() { EmployeeImpl emp = new EmployeeImpl("a1"); // Add an employee: this.template.save(emp); // Verify: List result = this.template.get(emp.getClass()); assertFalse(result.isEmpty()); // Delete all: this.template.delete(emp.getClass()); // Try to get all employees and verify that an empty list is returned: result = this.template.get(emp.getClass()); assertTrue(result.isEmpty()); } public void testExecuteCallback() { EmployeeImpl emp1 = new EmployeeImpl("a1"); EmployeeImpl emp2 = new EmployeeImpl("a2"); this.template.save(emp1); this.template.save(emp2); assertNull(emp1.getFirstname()); assertNull(emp1.getSurname()); // Execute a callback which looks for a1 and update it: PrevaylerCallback callback = new SimpleSearchAndUpdatePrevaylerCallback(); // The callback execution returns a list of one employee: List result = (List) this.template.execute(callback); assertEquals(1, result.size()); // Get it: emp1 = (EmployeeImpl) result.get(0); // Verify the update: assertTrue(emp1.getFirstname().equals("Sergio")); assertTrue(emp1.getSurname().equals("Bossa")); // Verify it is the same as the one directly retrieved from the prevalent system: EmployeeImpl emp1_1 = (EmployeeImpl) this.template.get(Employee.class, emp1.getId()); assertSame(emp1, emp1_1); } public void testConcurrentUpdates() throws Exception { EmployeeImpl emp = new EmployeeImpl("a1"); this.template.save(emp); final Object id = emp.getId(); Runnable r1 = new Runnable() { public void run() { PrevaylerTemplateTest.this.template.execute(new SleepingPrevaylerCallback(id)); } }; Runnable r2 = new Runnable() { public void run() { PrevaylerTemplateTest.this.template.execute(new NonSleepingPrevaylerCallback(id)); } }; Thread t1 = new Thread(r1); Thread.sleep(300); Thread t2 = new Thread(r2); t1.start(); t2.start(); t1.join(); t2.join(); } public void setPrevaylerTemplate(PrevaylerTemplate template) { this.template = template; } protected String[] getConfigLocations() { return new String[]{"testContext.xml"}; } }