Java 外键未存储在子实体中(一对多)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2521659/
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
Foreign key not stored in child entity (one-to-many)
提问by Kamil ?o?
I'm quite new to hibernate and have stumbled on this problem, which I can't find solution for.
我对休眠很陌生,偶然发现了这个问题,我找不到解决方案。
When persisting parent object (with one-to-manyrelationship with child), the foreign-key to this parent is not stored in child's table.
当持久化父对象(与子对象具有一对多关系)时,该父对象的外键不存储在子对象表中。
My classes:
我的课程:
Parent.java
父程序
@javax.persistence.Table(name = "PARENT")
@Entity
public class PARENT {
private Integer id;
@javax.persistence.Column(name = "ID")
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
private Collection<Child> children;
@OneToMany(mappedBy = "parent", fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
@Cascade({org.hibernate.annotations.CascadeType.ALL})
public Collection<Child> getChildren() {
return children;
}
public void setChildren(Collection<Child> children) {
this.children = children;
}
}
Child.java
子程序
@javax.persistence.Table(name = "CHILD")
@Entity
@IdClass(Child.ChildId.class)
public class Child {
private String childId1;
@Id
public String getChildId1() {
return childId1;
}
public void setChildId1(String childId1) {
this.childId1 = childId1;
}
private String childId2;
@Id
public String getChildId2() {
return childId2;
}
public void setChildId2(String childId2) {
this.childId2 = childId2;
}
private Parent parent;
@ManyToOne
@javax.persistence.JoinColumn(name = "PARENT_ID", referencedColumnName = "ID")
public Parent getParent() {
return parent;
}
public void setParent(Operation parent) {
this.parent = parent;
}
public static class ChildId implements Serializable {
private String childId1;
@javax.persistence.Column(name = "CHILD_ID1")
public String getChildId1() {
return childId1;
}
public void setChildId1(String childId1) {
this.childId1 = childId1;
}
private String childId2;
@javax.persistence.Column(name = "CHIILD_ID2")
public String getChildId2() {
return childId2;
}
public void setChildId2(String childId2) {
this.childId2 = childId2;
}
public ChildId() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ChildId that = (ChildId) o;
if (childId1 != null ? !childId1.equals(that.childId1) : that.childId1 != null)
return false;
if (childId2 != null ? !childId2.equals(that.childId2) : that.childId2 != null)
return false;
return true;
}
@Override
public int hashCode() {
int result = childId1 != null ? childId1.hashCode() : 0;
result = 31 * result + (childId2 != null ? childId2.hashCode() : 0);
return result;
}
}
}
Test.java
测试.java
public class Test() {
private ParentDao parentDao;
public void setParentDao(ParentDao parentDao) {
this.parentDao = parentDao;
}
private ChildDao childDao;
public void setChildDao(ChildDao childDao) {
this.childDao = parentDao;
}
test1() {
Parent parent = new Parent();
Child child = new Child();
child.setChildId1("a");
child.setChildId2("b");
ArrayList<Child> children = new ArrayList<Child>();
children.add(child);
parent.setChildren(children);
parent.setValue("value");
parentDao.save(parent); //calls hibernate's currentSession.saveOrUpdate(entity)
}
test2() {
Parent parent = new Parent();
parent.setValue("value");
parentDao.save(parent); //calls hibernate's currentSession.saveOrUpdate(entity)
Child child = new Child();
child.setChildId1("a");
child.setChildId2("b");
child.setParent(parent);
childDao.save(); //calls hibernate's currentSession.saveOrUpdate(entity)
}
}
When calling test1(), both entities get written to database, but field PARENT_ID in CHILD table stays empty.
调用test1() 时,两个实体都会写入数据库,但 CHILD 表中的字段 PARENT_ID 保持为空。
The only workaround I have so far is test2()- persisting parent first, and then the child.
到目前为止,我唯一的解决方法是test2()- 首先是持久化父级,然后是子级。
My goal is to persist parent and its children in one call to save()on Parent. Any ideas?
我的目标是在Parent上对save() 的一次调用中保留 parent 及其子项。有任何想法吗?
采纳答案by dr jerry
You can also add an extra method to your parent like
您还可以向您的父母添加额外的方法,例如
public void addChild(Child child)
which does something like
它做了类似的事情
child.setParent(this);
回答by Kevin Crowell
The problem is, in test1(), you are saving the child before you save the parent. In test2(), you are saving the parent first, then the child, which is correct, and is why it is working.
问题是,在 test1() 中,您在保存父项之前先保存子项。在 test2() 中,您首先保存父对象,然后保存子对象,这是正确的,这就是它起作用的原因。
Think about it this way. Can you be born before your mother and father are born? No, they must exist before you can exist. Crate the parent, then the child, as you do in test2().
这样想想。你能在你父母出生之前出生吗?不,它们必须存在才能存在。像在 test2() 中所做的那样,先将父项打包,然后再打包子项。
If you want, you can edit you parentDAO.save() to save or update any referenced children. That way, they save with 1 call.
如果需要,您可以编辑 parentDAO.save() 以保存或更新任何引用的子项。这样,他们节省了 1 个电话。
回答by Rob Heiser
Before you save the parent, it hasn't been assigned an ID. So, when you save the child first, it has no foreign key to save. You want to do it like test2(), but wrap in in a transaction. Take a look here. I think the section titled "Transaction demarcation with EJB/CMT" may be what you want.
在保存父级之前,尚未为其分配 ID。所以,当你先保存孩子时,它没有外键可以保存。您想像 test2() 那样做,但要包含在事务中。看看这里。我认为标题为“使用 EJB/CMT 进行事务划分”的部分可能是您想要的。
回答by Miigaa
I have a good solution for that case:D
我有一个很好的解决方案:D
mappedBy means inverse = "true". so you must inverse = "false"
mappingBy 表示inverse = "true"。所以你必须反转 = "false"
try it..
尝试一下..
@OneToMany(fetch = FetchType.EAGER, cascade ={CascadeType.ALL})//javax.persistent.CascadeType
@JoinColumn(name = "parent_id")//parent's foreign key
public Collection<Child> getChildren() {
return children;
}
I hope it s good to be work
我希望工作很好
回答by Mayur
Main problem in test1() is that you are not setting parent in child object. you should say.. child.setParent(parent). just setting child in parent doesn't mean that child is aware of parent. in fact, its child which owns relationship. so, its necessary to set parent in the child object. sequence of saveorUpdate() call on parent or child is immaterial.
test1() 中的主要问题是您没有在子对象中设置父对象。你应该说.. child.setParent(parent)。只是在父母中设置孩子并不意味着孩子知道父母。事实上,它的孩子拥有关系。所以,有必要在子对象中设置父级。对父级或子级调用 saveorUpdate() 的顺序无关紧要。
test2() is working because you have set parent in child object by calling child.setParent(). THis is missing in test1().
test2() 正在工作,因为您已经通过调用 child.setParent() 在子对象中设置了父级。这在 test1() 中是缺失的。