Persist 1st objects with composite primary key in sleep mode

I have a lower 1st relationship to facilities that are a mentor for students. The mentor has a composite primary key that I use as a foreign key in student

@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 } 

Then I repeat the above as shown below, but only the mentor is saved when the students table is empty.

How can I inherit a mentor with students?

 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); 
+7
java orm hibernate jpa hibernate-mapping
source share
5 answers

Try changing student field annotation to

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

+2
source share

When you use a composite key that displays as embeddable, you need to use @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 } 

and the student becomes:

 @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 used when both @Id and @ManyToOne use the same database columns, which is not the case for you, since you have a numeric identifier and a composite foreign key.

+2
source share

You may need to create a link from student to mentor in each student.

So, in your code after creating m you need to:

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

Otherwise, Hibernate may not know what to fill in the name_fk and address_fk columns with.

+2
source share

How about a change:

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

in

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

or

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

try not to miss

  = new HashSet(); 

part

+1
source share

As I understand your request, you would like the mentor to be the owner of the relationship. You will not get this with the line @OneToMany(mappedBy="mentor") . This actually puts the student as the owner of the relationship.

I tested this domain model and made several modifications to the annotations so that the test code works as you expect.

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 } 

It even works without execution: s1.setMentor(m);s2.setMentor(m); . I did not expect this, but it seems that sleep mode is coping with this.

Related article here .

Caution: delete database tables after changing annotations to allow hibernate to recreate tables.

+1
source share

All Articles