I have below 1-m relationship on entities which Mentor to Students. The mentor has composite primary key which i use as 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
}
I then persist the above as below but only the mentor is persisted where student table is empty.
How can I persist the 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);
Try changing annotation of students field to
@OneToMany(mappedBy="mentor", cascade = CascadeType.PERSIST)
When you use a composite-key, mapped as an 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
}
The @MapsId
is used when both the @Id
and the @ManyToOne
share the same database columns, which is not your case, since you have a numeric identifier and a composite foreign-key.
You may need to create the reference from Student to Mentor in each Student.
So in your code, after you create m
you need to:
s1.setMentor(m);
s2.setMentor(m);
Otherwise Hibernate may not know what to populate columns name_fk
and address_fk
with.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With