无法删除属于@ManyToOne关系的JPA实体

时间:2017-04-05 08:15:35

标签: java hibernate jpa spring-boot spring-data-jpa

我有两个域对象:

@Entity
public class Employee {
  @Id
  @Column(nullable = false, name = "id")
  protected Integer id;

  // Note: org_id is just an integer column in the database
  @JoinColumn(nullable = true, name = "org_id")
  @ManyToOne(targetEntity = Org.class)
  private Org org;
}

...和

@Entity
public class Org {
  @Id
  @Column(nullable = false, name = "id")
  protected Integer id;
}

我已经了解了我的逻辑情况,我需要对数据库中实际保存的内容进行一些重大更改。即一些Orgs被删除,其中的员工正在重新分配。

我遇到的问题是我的程序逻辑目前执行以下操作:

  1. 删除需要通过org.springframework.data.repository.delete(Iterable<? extends T> itrbl)
  2. 删除的所有员工
  3. 删除需要通过org.springframework.data.repository.delete(Iterable<? extends T> itrbl)
  4. 删除的所有组织
  5. 通过org.springframework.data.repository.save(Iterable<S> itrbl)
  6. 创建新的/更新现有组织
  7. 通过org.springframework.data.repository.save(Iterable<S> itrbl)
  8. 创建新的/更新现有员工

    问题出现在第2步。我得到一个像这样的例外:

      

    org.springframework.dao.InvalidDataAccessApiUsageException:   org.hibernate.TransientPropertyValueException:对象引用一个   未保存的瞬态实例 - 保存之前的瞬态实例   flushing:com.sample.domain.Employee.org - &gt; com.sample.domain.Org;   嵌套异常是java.lang.IllegalStateException:   org.hibernate.TransientPropertyValueException:对象引用一个   未保存的瞬态实例 - 保存之前的瞬态实例   刷新:com.sample.domain.Employee.org    - &GT; com.sample.domain.Org

    如果组织没有员工,我不想删除组织。同样,如果组织的员工被删除,我也不希望删除组织。

    我基本上只想要一些与我在employees表上的PostgreSQL中设置外键的方式相同的东西:

      CONSTRAINT fk_employees_org_id FOREIGN KEY (org_id)
          REFERENCES public.orgs (id) MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE SET NULL
    

    我查看了级联选项,我不确定它是否适用,因为它不是直接的父/子关系(定义{{​​1}}关系的Employee不是真的是父母 - 它是孩子)并且它不是双向的(没有必要让Org拥有所有员工的名单)

1 个答案:

答案 0 :(得分:2)

您不想要cascade,因为您已经说过自己不希望删除相关对象(并且这就是级联所做的一切)。

如果需要删除Org但仍有FK指向它,那么只需将OrgEmployee的链接归零即可...删除Org。您可以通过JPQL查询来检索链接到特定Employee的所有Org个对象,然后将其关联字段置空。或者,批量更新可以一次完成(但要注意内存中的对象,因为他们需要refresh()调用它们来获取FK的这个空值。)