diff --git a/src/main/java/dgpena/siexample/persistence/Department.java b/src/main/java/dgpena/siexample/persistence/Department.java index b6883060ebc5edd650553db23b300b1934d64f35..a423158fa18578fd99d8d6f94bd6180bc3b8db1c 100644 --- a/src/main/java/dgpena/siexample/persistence/Department.java +++ b/src/main/java/dgpena/siexample/persistence/Department.java @@ -1,9 +1,14 @@ package dgpena.siexample.persistence; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.OneToMany; @Entity public class Department { @@ -14,6 +19,9 @@ public class Department { private String name; + @OneToMany(mappedBy="department") + private Set employees = new HashSet(); + public int getId() { return id; } @@ -25,4 +33,24 @@ public class Department { public void setName(String name) { this.name = name; } + + public Set getEmployees() { + return Collections.unmodifiableSet(employees); + } + + public void addEmployee(Employee e) { + e.setDepartment(this); + } + + public void removeEmployee(Employee e) { + e.setDepartment(null); + } + + void internalAddEmployee(Employee e) { + this.employees.add(e); + } + + void internalRemoveEmployee(Employee e) { + this.employees.remove(e); + } } diff --git a/src/main/java/dgpena/siexample/persistence/Departments.java b/src/main/java/dgpena/siexample/persistence/Departments.java index 87463e746b4f58571eb982d316d065b10d23a210..a3b5c2b6ac6e96800069a500073e614f36dd0c7c 100644 --- a/src/main/java/dgpena/siexample/persistence/Departments.java +++ b/src/main/java/dgpena/siexample/persistence/Departments.java @@ -21,6 +21,10 @@ public class Departments { } public void deleteDepartment(Department d) { + // remove first my employees + for (Employee e: d.getEmployees()) { + e.setDepartment(null); + } em.remove(d); } diff --git a/src/main/java/dgpena/siexample/persistence/Employee.java b/src/main/java/dgpena/siexample/persistence/Employee.java new file mode 100644 index 0000000000000000000000000000000000000000..4ab9e2ed3459c851b2501523848af8b3b88df8b8 --- /dev/null +++ b/src/main/java/dgpena/siexample/persistence/Employee.java @@ -0,0 +1,49 @@ +package dgpena.siexample.persistence; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToOne; + +@Entity +public class Employee { + + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + private int id; + + private String name; + + @ManyToOne + private Department department; + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Department getDepartment() { + return department; + } + + public void setDepartment(Department department) { + if (this.department != null) { + this.department.internalRemoveEmployee(this); + } + + this.department = department; + + if (this.department != null) { + department.internalAddEmployee(this); + } + } + +} diff --git a/src/main/java/dgpena/siexample/persistence/Employees.java b/src/main/java/dgpena/siexample/persistence/Employees.java new file mode 100644 index 0000000000000000000000000000000000000000..95d24d50b9c8daadde5dcb9ab1bfbb33a2a20dc5 --- /dev/null +++ b/src/main/java/dgpena/siexample/persistence/Employees.java @@ -0,0 +1,17 @@ +package dgpena.siexample.persistence; + +import javax.persistence.EntityManager; + +public class Employees { + + private EntityManager em; + + public Employees(EntityManager em) { + this.em = em; + } + + public void addNewEmployee(Employee e) { + this.em.persist(e); + } + +} diff --git a/src/main/java/dgpena/siexample/persistence/Project.java b/src/main/java/dgpena/siexample/persistence/Project.java new file mode 100644 index 0000000000000000000000000000000000000000..78d6b19dadce2772cec79f3b90e0f90e09fbe13d --- /dev/null +++ b/src/main/java/dgpena/siexample/persistence/Project.java @@ -0,0 +1,56 @@ +package dgpena.siexample.persistence; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +@Entity +public class Project { + + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + private int id; + + private String name; + + @OneToMany(mappedBy="project") + private Set projectAssignments = new HashSet<>(); + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Set getEmployees() { + Set employees = new HashSet<>(); + + for (ProjectAssignment pa : projectAssignments) { + employees.add(pa.getEmployee()); + } + + return employees; + } + + void internalRemoveProjectAssignment(ProjectAssignment projectAssignment) { + this.projectAssignments.remove(projectAssignment); + + } + + void internalAddProjectAssignment(ProjectAssignment projectAssignment) { + this.projectAssignments.add(projectAssignment); + + } + +} diff --git a/src/main/java/dgpena/siexample/persistence/ProjectAssignment.java b/src/main/java/dgpena/siexample/persistence/ProjectAssignment.java new file mode 100644 index 0000000000000000000000000000000000000000..10855d7c1895817f80b53131c3e346165cb775cf --- /dev/null +++ b/src/main/java/dgpena/siexample/persistence/ProjectAssignment.java @@ -0,0 +1,97 @@ +package dgpena.siexample.persistence; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.IdClass; +import javax.persistence.ManyToOne; + +@Entity +@IdClass(ProjectAssignment.ProjectAssignmentId.class) +public class ProjectAssignment { + + @Id + @ManyToOne + private Project project; + + @Id + @ManyToOne + private Employee employee; + + + private Date startDate; + + + public Project getProject() { + return project; + } + + public Employee getEmployee() { + return employee; + } + + public void setProject(Project project) { + if (this.project != null) { + project.internalRemoveProjectAssignment(this); + } + this.project = project; + + if (this.project != null) { + this.project.internalAddProjectAssignment(this); + } + this.project = project; + } + + public void setEmployee(Employee employee) { + this.employee = employee; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public static class ProjectAssignmentId implements Serializable { + private int project; + private int employee; + + + public ProjectAssignmentId() {} + public ProjectAssignmentId(int project, int employee) { + super(); + this.project = project; + this.employee = employee; + } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + employee; + result = prime * result + project; + return result; + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ProjectAssignmentId other = (ProjectAssignmentId) obj; + if (employee != other.employee) + return false; + if (project != other.project) + return false; + return true; + } + + + } + +} diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml index 88d3e82f130d7aa07cec4a040a40611889b5a719..febc7c632c8a007312fd293c1b9e2d0842c5708a 100644 --- a/src/main/resources/META-INF/persistence.xml +++ b/src/main/resources/META-INF/persistence.xml @@ -4,7 +4,9 @@ version="2.0"> dgpena.siexample.persistence.Department - + dgpena.siexample.persistence.Employee + dgpena.siexample.persistence.Project + dgpena.siexample.persistence.ProjectAssignment diff --git a/src/test/java/dgpena/siexample/persistence/DepartmentsTest.java b/src/test/java/dgpena/siexample/persistence/DepartmentsTest.java index e3a680743d81e65bd1aa7d9548b6f9f09d0072f8..d9d411a7e868898fba4284369c8b4d1df5e90566 100644 --- a/src/test/java/dgpena/siexample/persistence/DepartmentsTest.java +++ b/src/test/java/dgpena/siexample/persistence/DepartmentsTest.java @@ -64,6 +64,28 @@ public class DepartmentsTest extends SQLBasedTest { } + @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); + + // 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); + + EntityManager em = emf.createEntityManager(); + Departments depts = new Departments(em); + Department d = depts.findById(deptId); + Set departmentEmployees = d.getEmployees(); + + assertEquals(1, departmentEmployees.size()); + assertEquals(empId, departmentEmployees.iterator().next().getId()); + + } + @Test public void testUpdateDepartment() throws SQLException { // insert a department previously with JDBC @@ -109,12 +131,44 @@ public class DepartmentsTest extends SQLBasedTest { assertEquals(0, rs.getInt("total")); } + @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); + + // 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); + + EntityManager em = emf.createEntityManager(); + Departments depts = new Departments(em); + Department d = depts.findById(deptId); + + em.getTransaction().begin(); + depts.deleteDepartment(d); + em.getTransaction().commit(); + + // check in the DB using JDBC + 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")); + } + + @Test public void testFindAllDepartments() throws SQLException { // insert a department previously with JDBC Statement statement = jdbcConnection.createStatement(); + + + statement.executeUpdate("UPDATE Employee set department_id = NULL WHERE department_id IS NOT NULL", Statement.RETURN_GENERATED_KEYS); statement.executeUpdate("DELETE FROM Department", Statement.RETURN_GENERATED_KEYS); + statement = jdbcConnection.createStatement(); statement.executeUpdate("INSERT INTO Department(name) values('dept-1')", Statement.RETURN_GENERATED_KEYS); diff --git a/src/test/java/dgpena/siexample/persistence/EmployeesTest.java b/src/test/java/dgpena/siexample/persistence/EmployeesTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3256abd6656d617cabaf4c7db931001bf60a1383 --- /dev/null +++ b/src/test/java/dgpena/siexample/persistence/EmployeesTest.java @@ -0,0 +1,65 @@ +package dgpena.siexample.persistence; + +import static org.junit.Assert.*; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class EmployeesTest extends SQLBasedTest { + +private static EntityManagerFactory emf; + + @BeforeClass + public static void setUpEntityManagerFactory() { + emf = Persistence.createEntityManagerFactory("si-database"); + } + + @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); + + EntityManager em = emf.createEntityManager(); + + Departments depts = new Departments(em); + Department dept = depts.findById(deptId); + + Employee e = new Employee(); + e.setName("pepe"); + e.setDepartment(dept); + + + Employees employees = new Employees(em); + + em.getTransaction().begin(); + + employees.addNewEmployee(e); + + // ensure that bi-directional relation is always consistent + assertEquals(1, dept.getEmployees().size()); + + em.getTransaction().commit(); + + int employeeId = e.getId(); + + + statement = jdbcConnection.createStatement(); + ResultSet res = statement.executeQuery("SELECT * from Employee where id = "+employeeId); + res.next(); + assertEquals(deptId, res.getInt("department_id")); + assertEquals("pepe", res.getString("name")); + + + } + +} diff --git a/src/test/resources/META-INF/persistence.xml b/src/test/resources/META-INF/persistence.xml index 81cb567a78c59605e7eb8cadb1f9b5a619aa7e4c..5f876e7882113e94dd6362eb611c1fc561bcc6a2 100644 --- a/src/test/resources/META-INF/persistence.xml +++ b/src/test/resources/META-INF/persistence.xml @@ -4,6 +4,10 @@ version="2.0"> dgpena.siexample.persistence.Department + dgpena.siexample.persistence.Employee + dgpena.siexample.persistence.Project + dgpena.siexample.persistence.ProjectAssignment +