问题描述
我有一个关于从子实体引用ParentEntities的问题ir
如果我有这样的事情:
Parent.java:
@Entity(name =Parent)
public class Parent {
@Id
@Generate ... ..
@Column
private int id;
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,mappedBy =parent)
private Set< Child>儿童;
simple ... getter and setter ...
}
和Child.java:
@Entity(name =Child)
public class Child {
@Id
@Generate ....
@Column
private int id;
@ManyToOne
私人父母;
...简单的getter a setter
}
表格将被创建:
父母:
int id
孩子:
int id
int parent_id(外键:parent.id)
好的,到目前为止,翻译很好。但是,当谈到使用Java的这个引用时,我想,你可以做这样的事情。
@Transactional
public void test(){
Parent parent = new Parent();
Child child = new Child();
设置< Child> children = new HashSet< Child>();
children.add(child);
parent.setChildren(children);
entityManager.persist(parent);
}
这导致数据库中出现这种情况:
父母:
id
100
孩子
id paren_id
101 100
但情况并非如此,您必须明确设置Parent to the Child(我认为,这个框架可能本身就可以做到)。
所以数据库真正的功能是这样的:
$ b $
父母:
id
100
孩子
id paren_id
101(null)
因为我没有将Parent设置为Child。所以我的问题:
我真的必须做某事吗?像这样?
Parent.java:
...
setChildren(Set< Child> children){
for(Child child:children){
child.setParent。(this);
}
this.children = children;
}
...
编辑:
根据快速回复,我可以通过在Reference-Owning Entity上使用@JoinColumn来解决这个问题。如果我们从上面看例子,我做了某事。像这样:
Parent.java:
@Entity(name =Parent)
public class Parent {
@Id
@Generate .....
@Column
private int id;
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
@JoinColumn(name =paren_id)
private Set< Child>儿童;
simple ... getter and setter ...
}
和Child.java:
@Entity(name =Child)
public class Child {
@Id
@Generate ....
@Column
private int id;
...简单的getter a setter
}
现在如果我们这样做:
@Transactional
public void test(){
Parent parent = new Parent ();
Child child = new Child();
设置< Child> children = new HashSet< Child>();
children.add(child);
parent.setChildren(children);
entityManager.persist(parent);
}
由Parent正确设置参考:
父母:
id
100
孩子
id paren_id
101 100
感谢您的回答。
这是一种策略,是的。
在双向关系中,关系有一个拥有和非拥有的一面。因为你的案例中拥有的一方在 Child
上,所以你需要设置关系以保持它。拥有方通常由您指定 @JoinColumn
的位置决定,但它看起来并不像您使用该注释,因此可能是因为您在父
注释中使用了 mappedBy
。
您可以。
i have a Question about referencing ParentEntities from Child Entites irIf i have something like this:
Parent.java:
@Entity(name ="Parent")
public class Parent {
@Id
@Generate.....
@Column
private int id;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "parent")
private Set<Child> children;
simple ... getter and setter ...
}
And the Child.java:
@Entity(name ="Child")
public class Child{
@Id
@Generate....
@Column
private int id;
@ManyToOne
private Parent parent;
... simple getter an setter
}
Following Tables are going to be created:
Parent:
int id
Child:
int id
int parent_id (foreign key: parent.id)
Ok, so far, everthings fine. But when it comes to using this Reference from Java, i would think, you can do something like this.
@Transactional
public void test() {
Parent parent = new Parent();
Child child = new Child();
Set<Child> children = new HashSet<Child>();
children.add(child);
parent.setChildren(children);
entityManager.persist(parent);
}
which leads to this in Database:
Parent:
id
100
Child
id paren_id
101 100
But thats not the case, you have to explicity set the Parent to the Child (which, i would think, the framework could probably do by itself).
So whats really in the database is this:
Parent:
id
100
Child
id paren_id
101 (null)
cause i haven't set the Parent to the Child. So my Question:
Do I really have to do sth. like this?
Parent.java:
...
setChildren(Set<Child> children) {
for (Child child : children) {
child.setParent.(this);
}
this.children = children;
}
...
Edit:
According to the fast Replies i was able to solve this Problem by using the @JoinColumn on the Reference-Owning Entity. If we take the Example from above, i did sth. like this:
Parent.java:
@Entity(name ="Parent")
public class Parent {
@Id
@Generate.....
@Column
private int id;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name= "paren_id")
private Set<Child> children;
simple ... getter and setter ...
}
And the Child.java:
@Entity(name ="Child")
public class Child{
@Id
@Generate....
@Column
private int id;
... simple getter an setter
}
Now if we do this:
@Transactional
public void test() {
Parent parent = new Parent();
Child child = new Child();
Set<Child> children = new HashSet<Child>();
children.add(child);
parent.setChildren(children);
entityManager.persist(parent);
}
The Reference is correctly set by the Parent:
Parent:
id
100
Child
id paren_id
101 100
Thanks for the Answers.
That is one strategy, yes.
On bi-directional relationships there is an "owning" and a "non-owning" side of the relationship. Because the owning side in your case is on Child
, you need to set the relationship there for it to be persisted. The owning side is usually determined by where you specify @JoinColumn
, but it doesn't look like you're using that annotation, so it's likely being inferred from the fact that you used mappedBy
in the Parent
annotation.
You can read a lot more about this here.
这篇关于JPA @OneToMany - >父 - 子参考(外键)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!