diff --git a/src/main/java/dgpena/siexample/persistence/Departments.java b/src/main/java/dgpena/siexample/persistence/Departments.java index a3b5c2b6ac6e96800069a500073e614f36dd0c7c..cc99f69f33b164858100d6cf86b3a95a7495658f 100644 --- a/src/main/java/dgpena/siexample/persistence/Departments.java +++ b/src/main/java/dgpena/siexample/persistence/Departments.java @@ -21,7 +21,7 @@ public class Departments { } public void deleteDepartment(Department d) { - // remove first my employees + // unassign employees to this department to preserve DB integrity for (Employee e: d.getEmployees()) { e.setDepartment(null); } diff --git a/src/main/java/dgpena/siexample/persistence/Employees.java b/src/main/java/dgpena/siexample/persistence/Employees.java index 95d24d50b9c8daadde5dcb9ab1bfbb33a2a20dc5..c9eee75d77d6e7d85c65915c43117cd291db9085 100644 --- a/src/main/java/dgpena/siexample/persistence/Employees.java +++ b/src/main/java/dgpena/siexample/persistence/Employees.java @@ -1,5 +1,7 @@ package dgpena.siexample.persistence; +import java.util.List; + import javax.persistence.EntityManager; public class Employees { @@ -13,5 +15,21 @@ public class Employees { public void addNewEmployee(Employee e) { this.em.persist(e); } - + + public Employee findById(int id) { + return em.find(Employee.class, id); + } + + public void deleteEmployee(Employee e) { + // First remove his/her project assignments (in order to preserve database integrity) + List projectAssignments = this.em.createQuery("SELECT pa FROM ProjectAssignment pa WHERE " + + "pa.employee = :e") + .setParameter("e", e).getResultList(); + + for (ProjectAssignment pa: projectAssignments) { + em.remove(pa); + } + + this.em.remove(e); + } } diff --git a/src/main/java/dgpena/siexample/persistence/Project.java b/src/main/java/dgpena/siexample/persistence/Project.java index 78d6b19dadce2772cec79f3b90e0f90e09fbe13d..04a8cb8d0b34c282804a6509f07d30cae6607550 100644 --- a/src/main/java/dgpena/siexample/persistence/Project.java +++ b/src/main/java/dgpena/siexample/persistence/Project.java @@ -1,8 +1,10 @@ package dgpena.siexample.persistence; +import java.util.Date; import java.util.HashSet; import java.util.Set; +import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; @@ -18,7 +20,7 @@ public class Project { private String name; - @OneToMany(mappedBy="project") + @OneToMany(mappedBy="project", cascade = {CascadeType.REMOVE, CascadeType.PERSIST}) private Set projectAssignments = new HashSet<>(); public int getId() { @@ -43,6 +45,15 @@ public class Project { return employees; } + public void addEmployee(Employee e, Date startDate) { + + ProjectAssignment pa = new ProjectAssignment(); + pa.setProject(this); + pa.setStartDate(startDate); + pa.setEmployee(e); + // the ProjectAssignment is automatically persisted due to CascadeType.PERSIST + } + void internalRemoveProjectAssignment(ProjectAssignment projectAssignment) { this.projectAssignments.remove(projectAssignment); @@ -50,7 +61,8 @@ public class Project { void internalAddProjectAssignment(ProjectAssignment projectAssignment) { this.projectAssignments.add(projectAssignment); - } + + } diff --git a/src/main/java/dgpena/siexample/persistence/Projects.java b/src/main/java/dgpena/siexample/persistence/Projects.java new file mode 100644 index 0000000000000000000000000000000000000000..268d9aac049ae656a7ee7202acb3d1d40505fabc --- /dev/null +++ b/src/main/java/dgpena/siexample/persistence/Projects.java @@ -0,0 +1,26 @@ +package dgpena.siexample.persistence; + +import javax.persistence.EntityManager; + +public class Projects { + + private EntityManager em; + + public Projects(EntityManager em) { + this.em = em; + } + + public void addNewProject(Project p) { + em.persist(p); + } + + public void deleteProject(Project p) { + // ProjectAssingment related instances are automatically removed due to CascadeType.REMOVE + em.remove(p); + } + + public Project findById(int id) { + return em.find(Project.class, id); + } + +} diff --git a/src/test/java/dgpena/siexample/persistence/DepartmentsTest.java b/src/test/java/dgpena/siexample/persistence/DepartmentsTest.java index fc2a628f68c9091c8ab0b8514aebe34a25ccfd24..b436607e7770f0abb8a1f1cda4c40a8f5805bb83 100644 --- a/src/test/java/dgpena/siexample/persistence/DepartmentsTest.java +++ b/src/test/java/dgpena/siexample/persistence/DepartmentsTest.java @@ -44,9 +44,7 @@ public class DepartmentsTest extends SQLBasedTest { @Test public void testFindById() throws SQLException { // insert a department previously with JDBC - Statement statement = jdbcConnection.createStatement(); - statement.executeUpdate("INSERT INTO Department(name) values('finanzas')", Statement.RETURN_GENERATED_KEYS); - int deptId = getLastInsertedId(statement); + int deptId = insertADepartment("finanzas"); EntityManager em = emf.createEntityManager(); Departments depts = new Departments(em); @@ -56,18 +54,14 @@ public class DepartmentsTest extends SQLBasedTest { assertEquals("finanzas", d.getName()); } - + @Test public void testFindByIdWithEmployees() throws SQLException { // insert a department previously with JDBC - Statement statement = jdbcConnection.createStatement(); - statement.executeUpdate("INSERT INTO Department(name) values('finanzas')", Statement.RETURN_GENERATED_KEYS); - int deptId = getLastInsertedId(statement); + int deptId = insertADepartment("finanzas"); // insert an employee in this department previously with JDBC - statement = jdbcConnection.createStatement(); - statement.executeUpdate("INSERT INTO Employee(name, department_id) values('pepe', "+deptId+")", Statement.RETURN_GENERATED_KEYS); - int empId = getLastInsertedId(statement); + int empId = insertAnEmployeeInADepartment(deptId); EntityManager em = emf.createEntityManager(); Departments depts = new Departments(em); @@ -78,13 +72,11 @@ public class DepartmentsTest extends SQLBasedTest { assertEquals(empId, departmentEmployees.iterator().next().getId()); } - + @Test public void testUpdateDepartment() throws SQLException { // insert a department previously with JDBC - Statement statement = jdbcConnection.createStatement(); - statement.executeUpdate("INSERT INTO Department(name) values('finanzas')", Statement.RETURN_GENERATED_KEYS); - int deptId = getLastInsertedId(statement); + int deptId = insertADepartment("finanzas"); EntityManager em = emf.createEntityManager(); Departments depts = new Departments(em); @@ -95,7 +87,7 @@ public class DepartmentsTest extends SQLBasedTest { em.getTransaction().commit(); // check in the DB using JDBC - statement = jdbcConnection.createStatement(); + Statement statement = jdbcConnection.createStatement(); ResultSet rs = statement.executeQuery("SELECT * FROM Department d where d.id = "+deptId); rs.next(); assertEquals("contabilidad", rs.getString("name")); @@ -105,9 +97,7 @@ public class DepartmentsTest extends SQLBasedTest { @Test public void testDeleteDepartment() throws SQLException { // insert a department previously with JDBC - Statement statement = jdbcConnection.createStatement(); - statement.executeUpdate("INSERT INTO Department(name) values('finanzas')", Statement.RETURN_GENERATED_KEYS); - int deptId = getLastInsertedId(statement); + int deptId = insertADepartment("finanzas"); EntityManager em = emf.createEntityManager(); Departments depts = new Departments(em); @@ -118,7 +108,7 @@ public class DepartmentsTest extends SQLBasedTest { em.getTransaction().commit(); // check in the DB using JDBC - statement = jdbcConnection.createStatement(); + Statement statement = jdbcConnection.createStatement(); ResultSet rs = statement.executeQuery("SELECT COUNT(*) as total FROM Department d where d.id = "+deptId); rs.next(); assertEquals(0, rs.getInt("total")); @@ -127,14 +117,12 @@ public class DepartmentsTest extends SQLBasedTest { @Test public void testDeleteDepartmentWithEmployees() throws SQLException { // insert a department previously with JDBC - Statement statement = jdbcConnection.createStatement(); - statement.executeUpdate("INSERT INTO Department(name) values('finanzas')", Statement.RETURN_GENERATED_KEYS); - int deptId = getLastInsertedId(statement); + int deptId = insertADepartment("finanzas"); // insert an employee in this department previously with JDBC - statement = jdbcConnection.createStatement(); - statement.executeUpdate("INSERT INTO Employee(name, department_id) values('pepe', "+deptId+")", Statement.RETURN_GENERATED_KEYS); - int empId = getLastInsertedId(statement); + insertAnEmployeeInADepartment(deptId); + + Statement statement; EntityManager em = emf.createEntityManager(); Departments depts = new Departments(em); @@ -151,7 +139,6 @@ public class DepartmentsTest extends SQLBasedTest { assertEquals(0, rs.getInt("total")); } - @Test public void testFindAllDepartments() throws SQLException { // insert a department previously with JDBC @@ -181,5 +168,16 @@ public class DepartmentsTest extends SQLBasedTest { assertTrue(namesToTest.isEmpty()); } - + + private int insertADepartment(String name) throws SQLException { + // insert a department previously with JDBC + Statement statement = jdbcConnection.createStatement(); + statement.executeUpdate("INSERT INTO Department(name) values('"+name+"')", Statement.RETURN_GENERATED_KEYS); + return getLastInsertedId(statement); + } + private int insertAnEmployeeInADepartment(int deptId) throws SQLException { + Statement statement = jdbcConnection.createStatement(); + statement.executeUpdate("INSERT INTO Employee(name, department_id) values('pepe', "+deptId+")", Statement.RETURN_GENERATED_KEYS); + return getLastInsertedId(statement); + } } diff --git a/src/test/java/dgpena/siexample/persistence/EmployeesTest.java b/src/test/java/dgpena/siexample/persistence/EmployeesTest.java index a1a5d317f91ff224552727912f313f1e6d7d8193..ec0ba038bb8b9694e76877dba1bb2d90ac7e467c 100644 --- a/src/test/java/dgpena/siexample/persistence/EmployeesTest.java +++ b/src/test/java/dgpena/siexample/persistence/EmployeesTest.java @@ -19,10 +19,8 @@ public class EmployeesTest extends SQLBasedTest { @Test public void testAddNewEmployee() throws SQLException { // insert a department previously with JDBC - Statement statement = jdbcConnection.createStatement(); - statement.executeUpdate("INSERT INTO Department(name) values('finanzas')", Statement.RETURN_GENERATED_KEYS); - int deptId = getLastInsertedId(statement); - + int deptId = insertADepartment(); + EntityManager em = emf.createEntityManager(); Departments depts = new Departments(em); @@ -47,7 +45,7 @@ public class EmployeesTest extends SQLBasedTest { int employeeId = e.getId(); - statement = jdbcConnection.createStatement(); + Statement statement = jdbcConnection.createStatement(); ResultSet res = statement.executeQuery("SELECT * from Employee where id = "+employeeId); res.next(); assertEquals(deptId, res.getInt("department_id")); @@ -55,5 +53,56 @@ public class EmployeesTest extends SQLBasedTest { } - + + @Test + public void testDeleteEmployeeWithProjectAssignment() throws SQLException { + + // insert an employee with JDBC + int employeeId = insertAnEmployee(); + + // create a project + int projectId = insertAProject(); + + // assign the employee to the project (which should be removed due to CascadeType.REMOVE + // in Project.projectAssignments) + Statement statement = jdbcConnection.createStatement(); + statement.executeUpdate("INSERT INTO ProjectAssignment(project_id, employee_id) values("+projectId+", " + +employeeId+")", Statement + .RETURN_GENERATED_KEYS); + + EntityManager em = emf.createEntityManager(); + + Employees employees = new Employees(em); + Employee e = employees.findById(employeeId); + + em.getTransaction().begin(); + employees.deleteEmployee(e); + em.getTransaction().commit(); + + statement = jdbcConnection.createStatement(); + ResultSet rs = statement.executeQuery("SELECT COUNT(*) as total FROM Employee e where e.id = "+employeeId); + rs.next(); + assertEquals(0, rs.getInt("total")); + } + + + private int insertADepartment() throws SQLException { + Statement statement = jdbcConnection.createStatement(); + statement.executeUpdate("INSERT INTO Department(name) values('finanzas')", Statement.RETURN_GENERATED_KEYS); + return getLastInsertedId(statement); + } + + private int insertAnEmployee() throws SQLException { + Statement statement = jdbcConnection.createStatement(); + statement.executeUpdate("INSERT INTO Employee(name) values('pepe')", Statement.RETURN_GENERATED_KEYS); + return getLastInsertedId(statement); + } + + private int insertAProject() throws SQLException { + Statement statement = jdbcConnection.createStatement(); + statement.executeUpdate("INSERT INTO Project(name) values('our best project')", Statement + .RETURN_GENERATED_KEYS); + return getLastInsertedId(statement); + } + } diff --git a/src/test/java/dgpena/siexample/persistence/ProjectsTest.java b/src/test/java/dgpena/siexample/persistence/ProjectsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..51028b0b8befdebc98c691b90b0ec88cc64a7f01 --- /dev/null +++ b/src/test/java/dgpena/siexample/persistence/ProjectsTest.java @@ -0,0 +1,163 @@ +package dgpena.siexample.persistence; + +import static org.junit.Assert.assertEquals; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Date; + +import javax.persistence.EntityManager; + +import org.junit.Test; + +public class ProjectsTest extends SQLBasedTest { + + @Test + public void testAddNewProject() throws SQLException { + EntityManager em = emf.createEntityManager(); + + Projects projects = new Projects(em); + + Project p = new Project(); + p.setName("Our best project"); + + + em.getTransaction().begin(); + + projects.addNewProject(p); + + em.getTransaction().commit(); + + int projectId = p.getId(); + + Statement statement = jdbcConnection.createStatement(); + ResultSet res = statement.executeQuery("SELECT COUNT(*) as total from Project where id = "+projectId); + res.next(); + assertEquals(1, res.getInt("total")); + } + + @Test + public void testAddEmployeeToProject() throws SQLException { + + // insert a project previously with JDBC + int projectId = insertAProject(); + + // insert an employee previously with JDBC + int employeeId = insertAnEmployee(); + + EntityManager em = emf.createEntityManager(); + + Projects projects = new Projects(em); + Project p = projects.findById(projectId); + + Employees employees = new Employees(em); + Employee e = employees.findById(employeeId); + + em.getTransaction().begin(); + + p.addEmployee(e, new Date()); + + em.getTransaction().commit(); + + + // ensure that a ProjectAssignment has been created + Statement statement = jdbcConnection.createStatement(); + ResultSet res = statement.executeQuery("SELECT COUNT(*) as total from ProjectAssignment where project_id = " + + ""+projectId+" and employee_id = "+employeeId); + res.next(); + assertEquals(1, res.getInt("total")); + } + + @Test + public void testCreateProjectAssignment() throws SQLException { + // insert a project previously with JDBC + int projectId = insertAProject(); + + // insert an employee previously with JDBC + int employeeId = insertAnEmployee(); + + EntityManager em = emf.createEntityManager(); + + em.getTransaction().begin(); + + Project p = new Projects(em).findById(projectId); + Employee e = new Employees(em).findById(employeeId); + + ProjectAssignment pa = new ProjectAssignment(); + pa.setProject(p); // pa is automatically added to the Project.projectAssignments collection + pa.setEmployee(e); + pa.setStartDate(new Date()); + // the ProjectAssignment is automatically persisted due to CascadeType.PERSIST present in Project.projectAssignments + + em.getTransaction().commit(); + + // ensure that a ProjectAssignment has been created using JDBC + Statement statement = jdbcConnection.createStatement(); + ResultSet res = statement.executeQuery("SELECT COUNT(*) as total from ProjectAssignment where project_id = " + + ""+projectId+" and employee_id = "+employeeId); + res.next(); + assertEquals(1, res.getInt("total")); + } + + @Test + public void testDeleteProject() throws SQLException { + // insert a project previously with JDBC + int projectId = insertAProject(); + + // insert an employee previously with JDBC + int employeeId = insertAnEmployee(); + + // assign the employee to the project (which should be removed due to CascadeType.REMOVE + // in Project.projectAssignments) + Statement statement = jdbcConnection.createStatement(); + statement.executeUpdate("INSERT INTO ProjectAssignment(project_id, employee_id) values("+projectId+", " + +employeeId+")", Statement + .RETURN_GENERATED_KEYS); + + EntityManager em = emf.createEntityManager(); + Projects projects = new Projects(em); + Project p = projects.findById(projectId); + + em.getTransaction().begin(); + projects.deleteProject(p); + em.getTransaction().commit(); + + // ensure that project doesn't exist using JDBC + statement = jdbcConnection.createStatement(); + ResultSet res = statement.executeQuery("SELECT COUNT(*) as total from Project where id = " + + ""+projectId); + res.next(); + assertEquals(0, res.getInt("total")); + } + + @Test + public void testGetEmployees() throws SQLException { + // insert a project previously with JDBC + int projectId = insertAProject(); + + // insert an employee previously with JDBC + int employeeId = insertAnEmployee(); + + // assign the employee to the project (which should be removed due to CascadeType.REMOVE + // in Project.projectAssignments) + Statement statement = jdbcConnection.createStatement(); + statement.executeUpdate("INSERT INTO ProjectAssignment(project_id, employee_id) values("+projectId+", " + +employeeId+")", Statement + .RETURN_GENERATED_KEYS); + } + + private int insertAProject() throws SQLException { + Statement statement = jdbcConnection.createStatement(); + statement.executeUpdate("INSERT INTO Project(name) values('our best project')", Statement + .RETURN_GENERATED_KEYS); + return getLastInsertedId(statement); + } + + private int insertAnEmployee() throws SQLException { + Statement statement = jdbcConnection.createStatement(); + statement.executeUpdate("INSERT INTO Employee(name) values('pepe')", Statement + .RETURN_GENERATED_KEYS); + return getLastInsertedId(statement); + } +}