new to JPA and hibernate, so please bear with me as I try to draw up a whole pic. So I have two Java objects that have bidirectional relationship. Employee class is the owning class and Department class is the inverse side of the relationship. A department can have many employees and a employee can have only one department. I assigned employee_id to be the primary key of the employee entity and department_id as the primary key of the department entity. I also want to use department_id as the foreign key in the employee class.
Employee class
@Entity
@Table(name = "Employee")
public class Employee
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
//primary key
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Employee_ID")
private Integer id;
//foreign key
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "Department_ID")
private Department department;
@Column(name = "Employee_name")
private String name;
public Employee() { }
public Employee(Integer id)
{
this.setId(id);
}
public void setDepartment(Department department){
this.department = department;
}
public Department getDepartment(){
return department;
}
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getEmployeeName(){
return name;
}
public void setEmployeeName(String name){
this.name = name;
}
Department class
@Entity
@Table(name = "Department")
public class Department
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Department_ID")
private Integer id;
@Column(name = "Department_name")
private String name;
@OneToMany(mappedBy="department", cascade=CascadeType.ALL)
private Collection<Employee> employees = new ArrayList<Employee>();
public Collection<Employee> getEmployees() {return employees;}
public void setEmployees(Collection<Employee> e){ employees = e;}
public Department() { }
public Department(Integer id)
{
this.setId(id);
}
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getDepartmentName(){
return name;
}
public void setDepartmentName(String name){
this.name = name;
}
Function I use to generate two objects and persist them in the database. The database I am testing with is H2 and the persistence.xml file is configured to drop all the tables initially so all tables is empty before the below function is called.
public static void populateTable() {
System.out.println("Populating tables");
Department d1 = new Department();
//d1.setId(1);
d1.setDepartmentName("finance");
//service.addDepartment(d1);
Employee e1 = new Employee();
e1.setEmployeeName("John");
//e1.setId(1);
//e1.setDepartment(d1);
//d1.getEmployees().add(e1);
service.addDepartment(d1);
service.addEmployee(e1);
}
Initially I tried to set the primary ids of created objects myself and I was getting "detached entity passed to persist" error. After reading a similar question, I understand that if I try to set the unique identifier before persisting the object, JPA will think the entity is already present in the database and it will throw a "detached entity passed to persist error". So I commented out callers to setter functions and above code runs fine. However if I try to link an employee to a department like what I did with e1.setDepartment(d1);
I would get this error detached entity passed to persist: com.javatunes.jpa.catalog.Department
. I have read many blogs such as this one and this post, but I still cannot find a solution to this problem. And one more thing the two persisting functions are defined as
public void addEmployee(Employee employee) {
em.persist(employee);
em.flush();
}
public void addDepartment(Department department){
em.persist(department);
em.flush();
}
The error is raised at em.persistent(employee).