Java JPA 未将外键保存到 @OneToMany 关系
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/814474/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JPA not saving foreign key to @OneToMany relation
提问by NA.
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. From my form i get a Contact object that have a list of Phone(numbers) in it. The Contact get persisted properly (Hibernate fetches an PK from the specified sequence). The list of Phone(numbers) also gets persisted with a correct PK, but there's no FK to the Contacts table.
我将 Spring 与 Hibernate 一起用作 JPA 提供程序,并尝试使用 @OneToMany(具有多个电话号码的联系人)将外键保存在电话号码表中。从我的表单中,我得到一个 Contact 对象,其中包含电话(号码)列表。Contact 得到正确的持久化(Hibernate 从指定的序列中获取一个 PK)。Phone(numbers) 列表也使用正确的 PK 持久化,但 Contacts 表没有 FK。
public class Contact implements Serializable {
@OneToMany(mappedBy = "contactId", cascade = CascadeType.ALL, fetch=FetchType.EAGER)
private List<Phone> phoneList;
}
public class Phone implements Serializable {
@JoinColumn(name = "contact_id", referencedColumnName = "contact_id")
@ManyToOne
private Contact contactId;
}
@Repository("contactDao")
@Transactional(readOnly = true)
public class ContactDaoImpl implements ContactDao {
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public void save(Contact c) {
em.persist(c);
em.flush();
}
}
@Controller
public class ContactController {
@RequestMapping(value = "/contact/new", method = RequestMethod.POST)
public ModelAndView newContact(Contact c) {
ModelAndView mv = new ModelAndView("contactForm");
contactDao.save(c);
mv.addObject("contact", c);
return mv;
}
}
Hopefully I got all of the relevant bits above, otherwise please let me know.
希望我得到了上面的所有相关信息,否则请告诉我。
采纳答案by cletus
You have to manage the Java relationships yourself. For this kind of thing you need something like:
您必须自己管理 Java 关系。对于这种事情,你需要这样的东西:
@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;
...
}
回答by mR_fr0g
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.
回复 Cletus 的回答。我会说@column
在 id 字段以及所有序列内容上都有注释很重要。使用@OneToMany
注释的mappedBy 参数的替代方法是使用@JoinColumn
注释。
As a kinda aside your implementation of addPhone needs looking at. It should probably be something like.
顺便说一下,您需要查看 addPhone 的实现。它应该是类似的。
public void addPhone(PhoneNumber phone) {
if (phone == null) {
return;
} else {
if (phoneNumbers == null) {
phoneNumbers = new ArrayList<Phone>();
}
phoneNumbers.add(phone);
phone.setContact(this);
}
}
回答by Camel
I don't think the addPhonemethod is necessary, you only have to set the contact in the phone object:
我不认为addPhone方法是必要的,你只需要在电话对象中设置联系人:
phone.setContact(contact);
回答by samsong8610
If the Contact-Phone relationship is unidirectional, you can also replace mappedBy
in @OneToMany
annotation with @JoinColumn(name = "contact_id")
.
如果 Contact-Phone 关系是单向的,您也可以mappedBy
在@OneToMany
注释中替换 为@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)
在JPA @OneToMany -> Parent - Child Reference (Foreign Key) 中类似
回答by Tom Chamberlain
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.
在您@OneToMany
的父实体之下。
nullable = false
IS VITALif you want hibernate to populate the fk on the child table
nullable = false
是至关重要的,如果你想Hibernate来填充子表上的FK
回答by Ilya Lysenko
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;
}