0

I was working with Hibernate and OneToMany Relationship, i came across a weird behavior today , although i did it purposely but i was not expecting this behavior

College.java

@Entity
@Table(name="COLLEGE")
public class College implements Serializable{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="COLLEGE_XID")
    private Long collegeId;

    @Column(name="COLLEGE_NAME")
    private String collegeName;

    @OneToMany(mappedBy="college",cascade = CascadeType.ALL) 
    private List<Student> studentList = new ArrayList<Student>();
    //... with get and setters
}

Student.java

@Entity
@Table(name = "STUDENT")
public class Student implements Serializable    {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="STUDENT_XID")
    private Long studentId;

    @Column(name="STUDENT_NAME")
    private String studentName;

    @ManyToOne
    @JoinColumn(name="COLLEGE_XID",nullable=false)
    private College college;
    //... with get and setters
}

Application.java

    College college1 = new BdCollege();
    college1.setCollegeName("C_1");

    College college2 = new BdCollege();
    college2.setCollegeName("C_2");

    Student student1 = new BdStudent();
    student1.setStudentName("S_1_C_2");

    CollegeDAO collegeDAO = new  CollegeDAO();

    // setting student 1 Parent to College 1        
    student1.setCollege(college1);   // <---- Here the Issue  ... student 1 as college 1 child

    // BUT assigning Student 1 as Child of Collge 2 in List 
    // i did it purposely to test the behaviour
    college2.getStudentList().add(student1);  // <---- Here the Issue ... but assigning it in the list of College 2 ... ws expecting Exception 

     // Saved College 1 & 2
     collegeDAO.save(college1);
     collegeDAO.save(college2);

      // Saved Successfully BUT

RESULT COLLEGE Table

 COLLEGE_XID     COLLEGE_NAME    
 --------------  --------------- 
 1               C_1             
 2               C_2 

STUDENT Table

 STUDENT_XID     STUDENT_NAME     COLLEGE_XID    
 --------------  ---------------  -------------- 
 1               S_1_C_2          1   

I was expecting some exception as assignment from child and parents mis-matched in college - student example and another thing that stucked me were the query generated by hibernate

Hibernate: insert into COLLEGE (COLLEGE_NAME) values (?)
Hibernate: insert into COLLEGE (COLLEGE_NAME) values (?)
Hibernate: insert into STUDENT (COLLEGE_XID, STUDENT_NAME) values (?, ?)

i.e it save College 1 first, Then College 2 Second and Saving Student as Child of College 2 but in the result it appears as child of College 1

Digital Alchemist
  • 2,324
  • 1
  • 15
  • 17
  • "Saving Student as Child of College 2" How can you be certain of this. You just see SQL without values. It may be saying the student with college_xid as 1 in the first place. – shazin Jul 16 '14 at 02:38
  • @shazin Well indeed this is not certain and :) this is not the real problem, for ur comment i have tried with different cases, Hibernate Generates SQL in the order the objects are saved... – Digital Alchemist Jul 16 '14 at 03:09
  • Its because you haven't got any cascades set anywhere. Because you have specified a `@JoinColumn` on your `@ManyToOne` a column exists for Hibernate to create an insert statement around. But because Hibernate doesn't know how to map your student list back to your persistent student object, it can't do anything with it. Just my $0.02 – JamesENL Jul 16 '14 at 04:19
  • @JamesMassey @OneToMany(mappedBy="college",cascade = CascadeType.ALL) cascades are mapped in College Class – Digital Alchemist Jul 16 '14 at 04:48
  • Herp derp, missed that. Perhaps Hibernate is taking the join column as precedence to the cascade. – JamesENL Jul 16 '14 at 04:50

1 Answers1

0

Its because you added mappedBy attribute and made student as owner of association. Since Student entity is the owner, it will maintain the relationship and hibernate will ignore changes on College side.

Ankit
  • 113
  • 1
  • 7