从集合中保存已删除子实体的父实体时处理EntityNotFoundException

时间:2017-04-12 11:19:41

标签: java hibernate jpa

我的问题很简单,但找到解决方案已成为一项相当繁琐而艰巨的任务。

我有两个休眠实体,

  1. Owner
  2. Dog
  3. Owner(或“父”实体)有三个字段

    1. name
    2. address
    3. dogsDog个实体的集合 - OneToMany关系。
    4. Dog的集合中删除Owner(通过Dog Repository从对象的集合和数据库中删除),以及更新所有者的地址,然后尝试要将更新的对象保存在数据库中,将抛出以下异常:

      javax.persistence.EntityNotFoundException: Unable to find project.pets.entities.Dog with id 10

      解决此问题的一种方法是,在Owner集合更新后,通过使用Dog调用所有者的Repository来获取findOne(ownerId)的新版本,在更新所有者的地址并将实体保存在数据库中之前。

      但这似乎不是一个合适的解决方案。

      我应该提到没有实现缓存。

      有没有人遇到这样的事情并设法妥善处理?

      编辑1:

      示例代码:

      者:

      @Entity
      @Table(name = "owners")
      public class Owner {
      
      ...
      
      @Column(name = "address")
      private String address;
      
      @OneToMany(fetch = FetchType.EAGER, mappedBy = "owner", 
                 cascade = {CascadeType.MERGE, CascadeType.REMOVE})
      private List<Dog> dogs;
      
      ...
      

      =============================================== ===

      犬:

      @Entity
      @Table(name = "dogs")
      public class Dog {
      
       ...
      
      @ManyToOne
      @JoinColumn(name = "owner_id")
      private Owner owner;
      
      ...
      

      =============================================== ===

      示例代码:

      Owner owner = ownerRepository.findOne(ownerId);
      Dog firstDog = owner.getDogs().get(0); // getting the first dog of the owner
      
      owner.getDogs().remove(0); // removing from object's collection
      dogRepository.delete(firstDog); // removing from DB
      
      owner.setAddress("new address");
      ownerRepository.save(owner);
      

1 个答案:

答案 0 :(得分:0)

您不需要执行dogRepository.delete(firstDog);:所有者已经负责传播从DB中删除您的条目。这就是为什么你有异常的原因:Hibernate已经删除了firstDog,所以当你再次调用dogRepository.delete(firstDog);时,Hibernate会因为无法找到你的实体而抱怨。