3 Replies Latest reply on Oct 11, 2005 8:48 AM by hypnotik

    EJB3.0 entities and relationships

    hypnotik

      Hello all!

      I'm developing a timesheet application. It consists of charges and employees. Charges can be either work charges or expense charges. Employee can have many work charges and/or expense charges but each charge belongs only to a single employee.

      I have developed EJB3.0 entities for employee, charge, work charge and expense charge. Charge is a superclass for both WorkCharge and ExpenseCharge. When I deploy these entities to the container new tables are created in the database. However, when I inspect these tables I find that both WORK_CHARGE and EXPENSE_CHARGE tables have a foreign key column for employee although I expect only the CHARGE table to have a foreign key column to EMPLOYEE table.

      Below is a code for entities. I would be grateful if someone could help me determine where I'm making mistake. Thank you in advance.



      ******************************************************

      /* Charge entity is superclass for both WorkCharge and ExpenseCharge
      entities. It must be abstract as charges can be either work or expense
      */

      package hr.ursic.timesheetEJB;
      import java.util.*;
      import javax.persistence.*;

      @Entity
      @Table(name="CHARGE")
      @Inheritance(strategy=InheritanceType.JOINED)
      public abstract class Charge {

      protected Long id;
      protected Date date;
      protected Employee employee;

      // accessor methods for work charge id
      @Id (generate=GeneratorType.AUTO)
      @Column (name="ID")
      public Long getId(){
      return id;
      }
      public void setId(Long id){
      this.id = id;
      }

      // accessor methods for work charge date
      @Column (name="CHARGE_DATE")
      public Date getDate(){
      return this.date;
      }
      public void setDate(Date date){
      this.date = date;
      }

      // accessor methods for employee
      @ManyToOne
      @JoinColumn (name="EMPLOYEE")
      public Employee getEmployee(){
      return employee;
      }
      public void setEmployee(Employee employee){
      this.employee = employee;
      }
      }


      /* WorkCharge entity represents work charges */

      package hr.ursic.timesheetEJB;
      import javax.persistence.*;

      @Entity
      @Table(name="WORK_CHARGE")
      public class WorkCharge extends Charge {

      private Double time;

      // accessor methods for work charge time
      @Column (name="CHARGE_TIME")
      public Double getTime(){
      return time;
      }
      public void setTime(Double time){
      this.time = time;
      }

      // retrieve work charge details
      @Transient
      public WorkChargeDetail getDetails(){
      WorkChargeDetail workChargeDetail = new WorkChargeDetail();
      workChargeDetail.setEmployeeId(getEmployee().getId());
      workChargeDetail.setDate(this.getDate());
      return workChargeDetail;
      }
      }


      /* Employee entity represents employees */

      package hr.ursic.timesheetEJB;
      import java.util.*;
      import javax.persistence.*;

      @Entity
      @Table(name = "EMPLOYEE")
      public class Employee {

      private Long id;
      private Collection workCharges;
      private Collection expenseCharges;

      // accessor methods for employee id
      @Id (generate = GeneratorType.AUTO)
      @Column (name = "ID")
      public Long getId(){
      return id;
      }
      public void setId(Long id){
      this.id = id;
      }

      // accessor methods for work charges
      @OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "employee")
      public Collection getWorkCharges(){
      return workCharges;
      }
      public void setWorkCharges(Collection workCharges){
      this.workCharges = workCharges;
      }

      // accessor methods for expense charges
      @OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "employee")
      public Collection getExpenseCharges(){
      return expenseCharges;
      }
      public void setExpenseCharges(Collection expenseCharges){
      this.expenseCharges = expenseCharges;
      }
      }

        • 1. Re: EJB3.0 entities and relationships
          hypnotik

          I'm sorry to have code messed up so here it is again.


          /* Charge entity is superclass for both WorkCharge and ExpenseCharge
          entities. It must be abstract as charges can be either work or expense
          */
          
          package hr.ursic.timesheetEJB;
          import java.util.*;
          import javax.persistence.*;
          
          @Entity
          @Table(name="CHARGE")
          @Inheritance(strategy=InheritanceType.JOINED)
          public abstract class Charge {
          
           protected Long id;
           protected Date date;
           protected Employee employee;
          
          // accessor methods for work charge id
           @Id (generate=GeneratorType.AUTO)
           @Column (name="ID")
           public Long getId(){
           return id;
           }
           public void setId(Long id){
           this.id = id;
           }
          
          // accessor methods for work charge date
           @Column (name="CHARGE_DATE")
           public Date getDate(){
           return this.date;
           }
           public void setDate(Date date){
           this.date = date;
           }
          
          // accessor methods for employee
           @ManyToOne
           @JoinColumn (name="EMPLOYEE")
           public Employee getEmployee(){
           return employee;
           }
           public void setEmployee(Employee employee){
           this.employee = employee;
           }
          }
          


          /* WorkCharge entity represents work charges */
          
          package hr.ursic.timesheetEJB;
          import javax.persistence.*;
          
          @Entity
          @Table(name="WORK_CHARGE")
          public class WorkCharge extends Charge {
          
           private Double time;
          
          // accessor methods for work charge time
           @Column (name="CHARGE_TIME")
           public Double getTime(){
           return time;
           }
           public void setTime(Double time){
           this.time = time;
           }
          
          // retrieve work charge details
           @Transient
           public WorkChargeDetail getDetails(){
           WorkChargeDetail workChargeDetail = new WorkChargeDetail();
           workChargeDetail.setEmployeeId(getEmployee().getId());
           workChargeDetail.setDate(this.getDate());
           return workChargeDetail;
           }
          }
          


          /* Employee entity represents employees */
          
          package hr.ursic.timesheetEJB;
          import java.util.*;
          import javax.persistence.*;
          
          @Entity
          @Table(name = "EMPLOYEE")
          public class Employee {
          
           private Long id;
           private Collection workCharges;
           private Collection expenseCharges;
          
          // accessor methods for employee id
           @Id (generate = GeneratorType.AUTO)
           @Column (name = "ID")
           public Long getId(){
           return id;
           }
           public void setId(Long id){
           this.id = id;
           }
          
          // accessor methods for work charges
           @OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "employee")
           public Collection getWorkCharges(){
           return workCharges;
           }
           public void setWorkCharges(Collection workCharges){
           this.workCharges = workCharges;
           }
          
          // accessor methods for expense charges
           @OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "employee")
           public Collection getExpenseCharges(){
           return expenseCharges;
           }
           public void setExpenseCharges(Collection expenseCharges){
           this.expenseCharges = expenseCharges;
           }
          }
          


          • 2. Re: EJB3.0 entities and relationships
            hypnotik

            As addition to previous posts, I use following code to store WorkCharges.


             public void storeWorkCharges(Collection<WorkChargeDetail> workCharges){
             Iterator iterator = workCharges.iterator();
             while(iterator.hasNext()){
             WorkCharge workCharge = new WorkCharge();
             WorkChargeDetail workChargeDetail = (WorkChargeDetail) iterator.next();
             workCharge.setDetails(workChargeDetail);
             Employee employee = entityManager.find(Employee.class,workChargeDetail.getEmployeeId());
             workCharge.setEmployee(employee);
             entityManager.persist(workCharge);
             employee.getWorkCharges().add(workCharge);
             }
             }
            


            The result is that CHARGE.EMPLOYEE holds FK to employee, but WORK_CHARGE.EMPLOYEE does not. But when I try to load work charges stored this way I cant load them from the database. What am I doing wrong?

            • 3. Re: EJB3.0 entities and relationships
              hypnotik

              I have managed to find a solution to this problem so consider the case closed.