我想用20个子实体来保持父实体,
我的代码如下
家长班
@OneToMany(mappedBy = "parentId")
private Collection<Child> childCollection;
儿童班
@JoinColumn(name = "parent_id", referencedColumnName = "parent_id")
@ManyToOne(optional=false)
private Parent parent;
String jsonString = "json string containing parent properties and child collection"
ObjectMapper mapper = new ObjectMapper();
Parent parent = mapper.readValue(jsonString, Parent.class);
public void save(Parent parent) {
Collection<Child> childCollection = new ArrayList<>() ;
for(Child tha : parent.getChildCollection()) {
tha.setParent(parent);
childCollection.add(tha);
}
parent.setChildCollection(childCollection);
getEntityManager().persist(parent);
}
所以,如果有20个子表,那么我必须在每个子表中设置父引用,因为我必须写20个for循环?
这可行吗?有没有其他方式或配置,我可以自动坚持父母和孩子?
修复您的父类:
@OneToMany(mappedBy = "parent")
的mappedBy 财产应该指向关系另一边的领域。如 的JavaDoc 说:
拥有这种关系的领域。除非关系是单向的,否则是必需的。
你也应该在周期中明确地持久化Child实体:
for(Child tha : parent.getChildCollection()) {
...
getEntityManager().persist(tha);
...
}
如 艾伦海伊 注释中注意到,您可以使用级联设施,让EntityManager自动保留所有子实体:
@OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)
有关cascades(和JPA本身)的更多详细信息,请参阅 Vlad Mihalcea的博客。
通常,@ JoinColumn表示实体是 这段关系的所有者 &mappedBy表示实体是 关系的逆。
所以,如果你想跟随
@OneToMany(mappedBy = "parent")
private Collection<Child> childCollection;
这意味着它 关系的逆 并且它不会为其子项设置父引用。
要设置对其子项的父引用,您必须创建上述实体 这段关系的所有者 以下列方式。
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn
private Collection<Child> childCollection;
您不需要设置任何子引用,因为上面的代码将在子表中创建一个列。
我会让父母坚持自己的孩子
package com.greg;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
@Entity(name = "PARENT")
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "NAME")
private String name;
@Column(name = "DESCRIPTION")
private String description;
@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name = "parent", referencedColumnName = "id", nullable = false)
private List<Child> children = new ArrayList<Child>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<Child> getChildren() {
return children;
}
public void setChildren(List<Child> children) {
this.children = children;
}
}
正如评论中指出的那样,您必须注意与子/父关系的对象图一致性。当JSON直接来自POST请求时,这种一致性将不会自由。
您必须使用标注父字段和子字段 @JsonBackReference
和 @JsonManagedReference
。
家长班:
@OneToMany(mappedBy = "parentId")
@JsonBackReference
private Collection<Child> childCollection;
儿童班:
@JoinColumn(name = "parent_id", referencedColumnName = "parent_id")
@ManyToOne(optional=false)
@JsonManagedReference
private Parent parent;
回答的类似问题是 这里
此外,如果你使用 @JsonBackReference
/@JsonManagedReference
上 javax.persistence
注释类与Lombok的组合 @ToString
您将在stackoverflow错误中出现的注释。
只是排除 childCollection
和 parent
来自的领域 @ToString
注释用 @ToString( exclude = ...)
龙目岛的生成也会发生同样的情况 equals()
方法 (@Data
, @EqualsAndHashCode
)。只需手动或使用即可实现这些方法 @Getter
和 @Setter
仅注释。