Spring Data JPA实体创建了两次

时间:2014-09-24 10:09:54

标签: java spring hibernate jpa

我编写了一个服务方法importCategories(),它从数据库中检索一个类别列表,并递归地填充属性和父类别。我遇到的问题是,当我使用complete()注释@Transactional时,新的类别会被创建两次,除了。任何人都可以向我解释为什么会这样吗?我在将子项添加到父项之前将其保存,然后在子集合上保存具有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);
    }

}

服务:

@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);
    }

}

1 个答案:

答案 0 :(得分:0)

如果你有一个级联ALL类型,那么你不需要先保存你的子实体,只需要保存父实体。

      category.getchildren().add(children)
      save(category)

在那一刻,类别将保存/更新实体,并将为儿童做同样的事情。 看看另一个例子,了解hibernate级联如何工作:http://www.mkyong.com/hibernate/hibernate-cascade-example-save-update-delete-and-delete-orphan/