2015-01-04 33 views
0

我有一對多的關係,就像你在這裏看到的那樣。我想要做的是我想用學生對象保存學校對象而不設置學生對象的學校。下面的代碼工作,但休眠插入空值到school_id_fk列。休眠時沒有參考的一對多關係

public class Student { 
.... 
@ManyToOne(cascade = CascadeType.ALL) 
@JoinColumn(name = "school_id_fk") 
private School school; 

} 

public class School{ 
.... 
@OneToMany(cascade = CascadeType.ALL, mappedBy = "school") 
private Set<Student> studentSet = new HashSet<Student>(0); 


} 

和主要方法;不需要

School school = new School(); 
    school.setSchoolName("school name"); 


    Student student = new Student(); 
    student.setStudentName("studentname1"); 
    student.setStudentSurname("studentsurname1"); 
    //student.setSchool(school); I don't want to set this line 

    Student student2 = new Student(); 
    student2.setStudentName("studentname2"); 
    student2.setStudentSurname("studentsurname2"); 
    //student2.setSchool(school); I don't want to set this line 


    SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); 
    Session session = sessionFactory.openSession(); 
    session.beginTransaction(); 

    school.getStudentSet().add(student); 
    school.getStudentSet().add(student2); 

    session.save(school); 

    session.getTransaction().commit(); 
    session.close(); 
    sessionFactory.close(); 

回答

2

@Funtik方法正確不使用的學校,但它需要第三個表。

但是你的方法也是正確的。你可以有雙向的關係。 如果您希望您的school_id_fk不爲空可以使用 Hibernate中的常見圖案(所謂的)方便的方法:

public class Student { 
    .... 
    @ManyToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name = "school_id_fk") 
    private School school; 

} 

public class School{ 
    .... 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "school") 
    private Set<Student> studentSet; 

    // this is private setter (used by hibernate internally) 
    private void setStudentSet(Set<Student> studentSet) { 
    this.studentSet = studentSet; 
    } 

    // this is public method (exposed API) 
    public void addStudent(Student) { 
    if (studentSet == null) { 
     studentSet = new HashSet<>(); 
    } 

    student.setSchool(this); 
    studentSet.add(student); 
    } 

} 

正如你所看到的(根據該模式),你應該隱藏studentSet因爲只有休眠應該使用setStudentSet() setter。 私人二傳手會做到這一點。但是您可以公開公共API以在此集合上運行 - addStudent()。 在addStudent(student)方法student對象被添加到設置和分配與父母學校在封裝的方式

總結:這是使用hibernate時常見的模式,隱藏集合設置器,暴露便利方法如addStudent()。 在這種方法中,您的FK列總是被填滿,並且您可以從沒有HQL查詢的Student對象中獲取School對象。在這種情況下,不需要第三張桌子。

這只是@Funtik解決方案的替代方案。

+0

感謝您的回答。這就是我一直在尋找的:) – hellzone 2015-01-04 14:35:14

1

的mappedBy在學校實體

public class School{ 
.... 
@OneToMany(cascade = CascadeType.ALL) 
@JoinColumn(name = "school_id") 
private Set<Student> studentSet = new HashSet<Student>(0); 

,並在學生實體

public class Student { 
.... 

} 
+0

當我刪除mappedBy屬性hibernate創建第三個表。有沒有辦法做到這一點,而不創建第三個表? – hellzone 2015-01-04 13:43:30

+0

是,更新了答案 – WeMakeSoftware 2015-01-04 14:49:12