Updating record in Many-to-one relationship
amitjadhav.ynwa Dec 28, 2012 2:19 AMI am trying out a simple example where I have an Employee table and a Department table where Many employees belong to a single department forming a Many to one relationship.
I have used the seam generated entity classes for both employee and department. I am using my custom EJB3 seam component to populate an employee details and to update them. Populating works file , but when i try to update seam updates the Department table instead of just changing the department number in the employee row. My code is as below.
@Entity
@Table(name = "EMP")
public class Emp implements java.io.Serializable {
private short empno;
private Dept dept;
private String ename;
private String job;
private Short mgr;
private Date hiredate;
private BigDecimal sal;
private BigDecimal comm;
public Emp() {
}
public Emp(short empno) {
this.empno = empno;
}
public Emp(short empno, Dept dept, String ename, String job, Short mgr,
Date hiredate, BigDecimal sal, BigDecimal comm) {
this.empno = empno;
this.dept = dept;
this.ename = ename;
this.job = job;
this.mgr = mgr;
this.hiredate = hiredate;
this.sal = sal;
this.comm = comm;
}
@Id
@Column(name = "EMPNO", unique = true, nullable = false, precision = 4, scale = 0)
public short getEmpno() {
return this.empno;
}
public void setEmpno(short empno) {
this.empno = empno;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "DEPTNO")
public Dept getDept() {
return this.dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
@Column(name = "ENAME", length = 10)
@Length(max = 10)
public String getEname() {
return this.ename;
}
public void setEname(String ename) {
this.ename = ename;
}
@Column(name = "JOB", length = 9)
@Length(max = 9)
public String getJob() {
return this.job;
}
public void setJob(String job) {
this.job = job;
}
@Column(name = "MGR", precision = 4, scale = 0)
public Short getMgr() {
return this.mgr;
}
public void setMgr(Short mgr) {
this.mgr = mgr;
}
@Temporal(TemporalType.DATE)
@Column(name = "HIREDATE", length = 7)
public Date getHiredate() {
return this.hiredate;
}
public void setHiredate(Date hiredate) {
this.hiredate = hiredate;
}
@Column(name = "SAL", precision = 7)
public BigDecimal getSal() {
return this.sal;
}
public void setSal(BigDecimal sal) {
this.sal = sal;
}
@Column(name = "COMM", precision = 7)
public BigDecimal getComm() {
return this.comm;
}
public void setComm(BigDecimal comm) {
this.comm = comm;
}
}
The department looks like
@Entity
@Table(name = "DEPT")
public class Dept implements java.io.Serializable {
private int deptno;
private String dname;
private String loc;
private Set<Emp> emps = new HashSet<Emp>(0);
public Dept() {
}
public Dept(int deptno) {
this.deptno = deptno;
}
public Dept(int deptno, String dname, String loc, Set<Emp> emps) {
this.deptno = deptno;
this.dname = dname;
this.loc = loc;
//this.emps = emps;
}
@Id
@OneToMany
@Column(name = "DEPTNO", unique = true, nullable = false, precision = 2, scale = 0)
public int getDeptno() {
return this.deptno;
}
public void setDeptno(int deptno) {
this.deptno = deptno;
}
@Column(name = "DNAME", length = 14)
@Length(max = 14)
public String getDname() {
return this.dname;
}
public void setDname(String dname) {
this.dname = dname;
}
@Column(name = "LOC", length = 13)
@Length(max = 13)
public String getLoc() {
return this.loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "dept")
public Set<Emp> getEmps() {
return this.emps;
}
public void setEmps(Set<Emp> emps) {
this.emps = emps;
}
}
And my EJB3 looks like
@Stateful
@Name("workflow")
@Scope(ScopeType.CONVERSATION)
public class WorkflowBean implements Workflow
{
@Logger private Log log;
@In StatusMessages statusMessages;
@PersistenceContext(type=PersistenceContextType.EXTENDED)
EntityManager entityManager;
@Out(required=false)
Emp employee = new Emp();
@RequestParameter("empEmpno")
String empNo;
public void workflow()
{
log.info("workflow.workflow() action called");
statusMessages.add("workflow");
}
@End
public boolean save(){
entityManager.setFlushMode(FlushModeType.COMMIT);
System.out.println("In Save---"+empNo);
try{
Dept dept = employee.getDept();
String deptName= dept.getDname();
System.out.println("The Dept Name--- "+deptName);
List<Emp> empList = entityManager.createQuery("SELECT e FROM Emp e WHERE e.empno=:empno").setParameter("empno", employee.getEmpno()).getResultList();
employee=empList.get(0);
Integer deptNo = (Integer) entityManager.createQuery("SELECT d.deptno FROM Dept d WHERE d.dname=:dname").setParameter("dname", deptName).getSingleResult();
Dept newDept = new Dept();
newDept = entityManager.find(Dept.class, deptNo.intValue());
employee.setDept(newDept);
entityManager.merge(employee);
return true;
}catch(Exception e){
return false;
}
}
@Begin(join=true)
public boolean populateEmp(){
entityManager.setFlushMode(FlushModeType.COMMIT);
System.out.println("The Emp No. is---"+empNo);
int no = Integer.parseInt(empNo);
short emp =(short)no;
employee = entityManager.find(Emp.class, emp);
entityManager.flush();
return true;
}
public Emp getEmployee() {
return employee;
}
public void setEmployee(Emp employee) {
this.employee = employee;
}
// add additional action methods
public String getEmpNo() {
return empNo;
}
public void setEmpNo(String empNo) {
this.empNo = empNo;
}
@Remove
@Destroy
public void destroy() {
}
}
Before doing `entityManager.setFlushMode(FlushModeType.COMMIT);` on each form submit my department entity was directly modified. I solved that but still can wrap my head around why it has to modify the department table. I have just started with Seam