3 Replies Latest reply on Aug 17, 2009 8:13 AM by wolfgangknauf

    Many to Many realtionship question

      Hi,
      I'm using a manyToMany relationship in my project and I have a question:
      Is it possible to update the relationship from both sides?
      I'll show you an example of what i mean:


      @Entity
      public class Student {
       @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
       private int id;
       private String name;
      
       @ManyToMany
       @JoinTable(name="Student_Dept",
       joinColumns=@JoinColumn(name="Stut_ID"),
       inverseJoinColumns=@JoinColumn(name="DEPT_ID"))
       private Collection<Department> departments;
       public Student() {
       departments = new ArrayList<Department>();
      }
      ...
       public Collection<Department> getDepartments() {
       return departments;
       }
      
       public void setDepartment(Collection<Department> departments) {
       this.departments = departments;
       }
      

      @Entity
      public class Department {
       @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
       private int id;
       private String name;
      
       @ManyToMany(mappedBy="departments")
       private Collection<Student> students;
      
       public Department(){
       students = new ArrayList<Student>();
       }
      ...
       public Collection<Student> getStudents() {
       return students;
       }
      
       public void setStudent(Collection<Student> students) {
       this.students = students;
       }
      


      Given that, In my main.java I can do this:
      Department dept = new Department();
      ...
       dept.addStudent(student1);
       em.persist(dept);
      

      and it works
      but if i try it the other way around
       student.addDept(dept1);
      

      it fails to update the database (no exception or anything - the changes simply do not reflect in the db)
      is that because i have to do it from one side only?

      note:
      This example is not my code but was taken from: http://www.java2s.com/Tutorial/Java/0355__JPA/ManyToManyJoinTableJoinInverseJoinColumn.htm
      it is similar enough though that you can use it as a reference.

      Thanks,
      Elad Katz


        • 1. Re: Many to Many realtionship question
          jaikiran

          This wiki https://www.jboss.org/community/wiki/EJB3relationships has good informative explanations on EJB3 entity relationships. See if it covers your case (probably does).

          • 2. Re: Many to Many realtionship question

            Hi jaikiran,
            Thanks for the quick reply, I have actually read this article before and indeed in my implementation I use Sets instead of a Collection as is recommended there.
            However, that article doesn't address my issue directly though it does say this:


            For a @ManyToMany relationship, it might look like this:

            LeftBean left = ...;
             RightBean right = ...;
             left.getRights().add(right);
             right.getLefts().add(left);
            
             this.entityManager.merge(left);


            which means that if I want to add multiple records to the left bean i would have to add it once in the right bean and for each of the left records i'm going to have to add this right bean to them, and then only commit (merge) one of them.
            that will work, but feels wrong - is this really the case?

            • 3. Re: Many to Many realtionship question
              wolfgangknauf

              Hi,

              you basically need two steps to persist data:

              1) create a correct in-memory state
              2) persist it

              It seems that your original use case failed in step 1: the relation has to be defined correct in memory, so that both sides know each other.

              If step 1 has the correct outcome, step 2 should work no matter which side is saved.

              BUT you should take care for your "Cascade" type: with a "@ManyToMany", the default is to cascade nothing. So, if your relationship contains a new child item, it is not inserted by default. You have to set "cascade = CascadeType.MERGE" to insert new childs when saving the parent.

              Hope this helps

              Wolfgang