2015-05-11 13 views
7

Tôi có dưới 1 m mối quan hệ trên các thực thể mà Cố vấn cho học sinh. Người cố vấn có khóa chính kết hợp mà tôi sử dụng làm khóa ngoài trong học sinhPersist 1-m thực thể với khóa chính composite trong hibernate

@Entity 
public class Mentor implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    private MentorPK id; 
    private String email; 
    @OneToMany(mappedBy="mentor") 
    private Set<Student> students; 

    public MentorPK getId() { 
     return id; 
    }    
    //getters and setters 
} 

@Embeddable 
public class MentorPK implements Serializable { 

    private static final long serialVersionUID = 1L; 
    private String name; 
    private String add; 
    //getters and setters 
    //override equals and hashcode 
} 


@Entity 
public class Student implements Serializable{ 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private int id; 
    private String name;  

    @ManyToOne 
    @MapsId("id") 
    @JoinColumns({ 
     @JoinColumn(name="name_fk", referencedColumnName="name"), 
     @JoinColumn(name="address_fk", referencedColumnName="address") 
    }) 
    private Mentor mentor; 

    //Getters and setters 
} 

Tôi sau đó vẫn tồn tại ở trên nhưng chỉ người cố vấn được duy trì ở nơi bảng học sinh trống.

Làm cách nào để tôi có thể tiếp tục cố vấn với sinh viên?

Set<Student> students = new HashSet<Student>(); 

Student s1 = new Student(); 
s1.setName("Student 1"); 

Student s2 = new Student(); 
s2.setName("Student 2"); 

students.add(s1); 
students.add(s2); 

MentorPK mpk = new MentorPK(); 
mpk.setAddress("C"); 
mpk.setName("D"); 

Mentor m = new Mentor(); 
m.setId(mpk); 
m.setEmail("emaill"); 
m.setStudents(students); 

studentManager.saveMentor(m); 
+0

Có lẽ đây thực sự là vấn đề với việc tạo khóa chính Id của Học sinh tự động. Bạn có thể tạo học sinh không có cố vấn không? – DuncanKinnear

+0

@DuncanKinnear yes tôi có thể – Harshana

Trả lời

2

Hãy thử thay đổi chú thích của lĩnh vực sinh viên

@OneToMany(mappedBy="mentor", cascade = CascadeType.PERSIST)

+0

không hoạt động bằng cách thêm thuộc tính cascade = CascadeType.PERSIST – Harshana

+0

Tôi vừa tạo một dự án mẫu nhỏ sử dụng mã bạn đã cung cấp (sửa địa chỉ/thêm tên trường không nhất quán và xóa chú thích @MapsId lỗi thời) và thêm chuỗi loại và nó hoạt động như mong đợi, sau khi gọi thực thểManager.persist (m) các sinh viên cũng đã kiên trì. –

+0

Tôi vừa nhận thấy rằng bạn đề cập đến ngủ đông, tôi đã tạo ví dụ bằng cách sử dụng eclipselink. Bạn có thể muốn thử sử dụng phiên bản mới nhất và nếu nó vẫn không hoạt động cho bạn thì hãy kiểm tra xem đây có phải là lỗi được báo cáo hay tự mình báo cáo lỗi đó. –

2

Khi bạn sử dụng một hỗn hợp-key, ánh xạ như một đối tượng nhúng bạn cần phải sử dụng @EmbeddedId:

@Entity 
public class Mentor { 

    @EmbeddedId 
    private MentorPK id; 

    private String email; 
    @OneToMany(mappedBy="mentor") 
    private Set<Student> students; 

    public MentorPK getId() { 
     return id; 
    }    
    //getters and setters 
} 

và Sinh viên trở thành:

@Entity 
public class Student { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private int id; 
    private String name;  

    @ManyToOne 
    @JoinColumns({ 
     @JoinColumn(name="name_fk", referencedColumnName="name"), 
     @JoinColumn(name="address_fk", referencedColumnName="address") 
    }) 
    private Mentor mentor; 

    //Getters and setters 
} 

@MapsId được sử dụng khi cả hai @Id@ManyToOne chia sẻ cùng một cột cơ sở dữ liệu, không phải trường hợp của bạn, vì bạn có số nhận dạng dạng số và khóa ngoài tổng hợp.

1

Làm thế nào về việc thay đổi:

@OneToMany(mappedBy="mentor") 
private Set<Student> students; 

tới:

@OneToMany(mappedBy="mentor") 
private Set<Student> students = new HashSet(); 

hoặc

@OneToMany(cascade=CascadeType.ALL) 
@JoinColumn(name="student_id") 
@org.hibernate.annotations.IndexColumn(name="idx") 
private Set<Student> students = new HashSet(); 

cũng cố gắng không để bỏ qua

= new HashSet(); 

part

2

Bạn có thể cần phải tạo tài liệu tham khảo từ Học sinh đến Cố vấn trong mỗi Học sinh.

Vì vậy, trong mã của bạn, sau khi bạn tạo m bạn cần phải:

s1.setMentor(m); 
s2.setMentor(m); 

Nếu không Hibernate có thể không biết những gì để cư cột name_fkaddress_fk với.

+0

không hoạt động như vậy. tôi đoán tôi phải kiên trì học sinh trước và sau đó kiên trì người cố vấn với học sinh – Harshana

1

Khi tôi hiểu yêu cầu của bạn, bạn muốn có Người cố vấn làm chủ sở hữu của mối quan hệ. Bạn không có được điều này với dòng @OneToMany(mappedBy="mentor"). Điều này thực sự đặt sinh viên là chủ sở hữu của mối quan hệ.

Tôi đã thử nghiệm mô hình miền này và đã thực hiện một số sửa đổi đối với chú thích để mã thử nghiệm hoạt động như bạn mong đợi.

Student

public class Student implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy= GenerationType.AUTO) 
    private int id; 
    private String name; 

    @ManyToOne 
    @JoinColumns({ 
      @JoinColumn(name="name_fk", referencedColumnName="name", insertable = false, updatable = false), 
      @JoinColumn(name="address_fk", referencedColumnName="address", insertable = false, updatable = false) 
    }) 
    private Mentor mentor; 

//setters and getters 
} 

Mentor

public class Mentor implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    private MentorPK id; 
    private String email; 
    @OneToMany(cascade = CascadeType.ALL) 
    @JoinColumns({ 
      @JoinColumn(name="name_fk", referencedColumnName="name"), 
      @JoinColumn(name="address_fk", referencedColumnName="address") 
    }) 
    private Set<Student> students; 
//setters and getters 
} 

Nó thậm chí hoạt động mà không thực hiện: s1.setMentor(m);s2.setMentor(m);. Tôi đã không mong đợi nó nhưng có vẻ như là ngủ đông là đối phó với điều này.

Bài viết có liên quan là here.

Chú ý: thả bảng cơ sở dữ liệu sau khi bạn thay đổi chú thích để cho phép ngủ đông tạo lại bảng.

+0

Cảm ơn. Nhưng thực sự tôi muốn học sinh trở thành chủ sở hữu của mối quan hệ. Đó là lý do tại sao tôi đặt mappedBy ở bên Mentor. Vì vậy, tôi nghĩ rằng mô hình là chính xác nhưng cách tôi kiên trì dữ liệu trong khách hàng là sai. Bạn có thể trả lời cách kiên trì học sinh với người cố vấn theo cách chính xác – Harshana

+0

Tôi thử dưới đây, Sinh viên s1 = new Student(); s1.setName ("Sinh viên 1"); \t \t MentorPK mpk = new MentorPK(); mpk.setAddress ("C"); mpk.setName ("D"); Mentor m = new Mentor(); m.setId (mpk); m.setEmail ("emaill"); \t \t s1.setMentor (m); //studentManager.saveMentor(m); studentManager.saveStudent (s1); Nhưng nó đã cho tôi "EntityNotFoundException: Không thể tìm thấy com.ejb.entities.Mentor với id [email protected]". Sau đó, tôi kiên trì người cố vấn trước khi cứu sinh viên. Sau đó, tôi đã không thể chèn NULL vào ("SYS". "HỌC SINH". "ADDRESS_FK") ngoại lệ – Harshana

Các vấn đề liên quan