I\'m using Spring with Hibernate as a JPA provider and are trying to get a @OneToMany (a contact having many phonenumbers) to save the foreign key in the phone numbers table
You have to manage the Java relationships yourself. For this kind of thing you need something like:
@Entity
public class Contact {
@Id
private Long id;
@OneToMany(cascade = CascadeType.PERSIST, mappedBy = "contact")
private List<Phone> phoneNumbers;
public void addPhone(PhoneNumber phone) {
if (phone != null) {
if (phoneNumbers == null) {
phoneNumbers = new ArrayList<Phone>();
}
phoneNumbers.add(phone);
phone.setContact(this);
}
}
...
}
@Entity
public class Phone {
@Id
private Long id;
@ManyToOne
private Contact contact;
...
}
If the Contact-Phone relationship is unidirectional, you can also replace mappedBy
in @OneToMany
annotation with @JoinColumn(name = "contact_id")
.
@Entity
public class Contact {
@Id
private Long id;
@OneToMany(cascade = CascadeType.PERSIST)
@JoinColumn(name = "contact_id")
private List<Phone> phoneNumbers;
// normal getter/setter
...
}
@Entity
public class PhoneNumber {
@Id
private Long id;
...
}
Similar in JPA @OneToMany -> Parent - Child Reference (Foreign Key)
I don't think the addPhone method is necessary, you only have to set the contact in the phone object:
phone.setContact(contact);
If you want your relationship unidirectional i.e. can navigate from Contact to Phone's only, you need to add
@JoinColumn(name = "contact_id", nullable = false)
Under your @OneToMany
on your parent entity.
nullable = false
IS VITAL if you want hibernate to populate the fk on the child table
In reply to Cletus' answer. I would say that it's important to have the @column
annotation on the id fields, as well as all the sequence stuff. An alternative to using the mappedBy parameter of the @OneToMany
annotation is to use the @JoinColumn
annotation.
As a kinda aside your implementation of addPhone needs looking at. It should probably be something like.
public void addPhone(PhoneNumber phone) {
if (phone == null) {
return;
} else {
if (phoneNumbers == null) {
phoneNumbers = new ArrayList<Phone>();
}
phoneNumbers.add(phone);
phone.setContact(this);
}
}
Try this sample:
@Entity
public class Contact {
@Id
private Long id;
@JoinColumn(name = "contactId")
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Phone> phones;
}
@Entity
public class Phone {
@Id
private Long id;
private Long contactId;
}