Java Spring数据JPA实体创建两次
我已经编写了一个服务方法Java Spring数据JPA实体创建两次,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,我已经编写了一个服务方法importCategories(),它从数据库中检索类别列表,并递归地填充属性和父类别。我遇到的问题是,新类别创建了两次,除非我用@Transactional注释complete()。有人能解释一下为什么会这样吗?在将子对象添加到父对象之前,我先保存子对象,然后在子对象集合中保存具有CascadeType.ALL的父对象 型号: @Entity public class Category implements Identifiable<Integer> {
importCategories()
,它从数据库中检索类别列表,并递归地填充属性和父类别。我遇到的问题是,新类别创建了两次,除非我用@Transactional
注释complete()
。有人能解释一下为什么会这样吗?在将子对象添加到父对象之前,我先保存子对象,然后在子对象集合中保存具有CascadeType.ALL
的父对象
型号:
@Entity
public class Category implements Identifiable<Integer> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private Integer key;
private String name;
@ManyToOne
private Category parent;
@OneToMany(mappedBy="parent", cascade = {CascadeType.ALL})
private List<Category> children = new ArrayList<Category>();
public void add(Category category) {
category.setParent(this);
children.add(category);
}
}
@实体
公共类类别实现了可识别的{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
私有整数id;
私钥;
私有字符串名称;
@许多酮
私人类别家长;
@OneToMany(mappedBy=“parent”,cascade={CascadeType.ALL})
private List children=new ArrayList();
公共无效添加(类别){
类别。setParent(本);
添加(类别);
}
}
服务:
@Transactional
private void complete(Category category) {
// ... (getting category info such as "name" and "parent key" from web service)
category.setName(name);
category = categoryRepository.saveAndFlush(category);
if (category.getParent() == null) {
Category parentCategory = new Category();
parentCategory.setKey(parentKey);
List<Category> categories = categoryRepository.findByKey(parentKey);
if (categories.size() > 0) {
parentCategory = categories.get(0);
}
parentCategory.add(category);
parentCategory = categoryRepository.saveAndFlush(parentCategory);
if (parentCategory.getParent() == null) {
complete(parentCategory);
}
}
}
public void importCategories() {
List<Category> list = categoryRepository.findAll();
for (Category category : list) {
complete(category);
}
}
@Transactional
私人作废完成(类别){
//…(从web服务获取类别信息,如“名称”和“父密钥”)
类别.集合名(名称);
category=categoryRepository.saveAndFlush(类别);
if(category.getParent()==null){
类别parentCategory=新类别();
parentCategory.setKey(parentKey);
List categories=categoryRepository.findByKey(parentKey);
如果(categories.size()>0){
parentCategory=categories.get(0);
}
parentCategory.add(类别);
parentCategory=categoryRepository.saveAndFlush(parentCategory);
if(parentCategory.getParent()==null){
完整(家长类别);
}
}
}
公共无效导入类别(){
List List=categoryRepository.findAll();
用于(类别:列表){
完整(类别);
}
}
如果您有一个cascade-ALL类型,那么您不需要先保存子实体,只保存父实体
category.getchildren().add(children)
save(category)
此时,类别将保存/更新实体,并对子项执行相同的操作。
查看其他示例以了解hibernate级联的工作原理: