Java 仅在某些记录上存在约束冲突spring JPA

Java 仅在某些记录上存在约束冲突spring JPA,java,database,spring,jpa,constraints,Java,Database,Spring,Jpa,Constraints,对于依赖实体,我得到了一个违反约束的异常,但它只发生在旧记录上。我的上一个更改是向名为KPIBusiness的父实体添加一个mappedBy=kpi-属性 我可以删除新创建的具有依赖项的父实体,但不能删除旧实体 KPIBusiness.java: @Entity public class KPIBusiness extends KPI { private Long businessProcessId; private String businessProcess; p

对于依赖实体,我得到了一个违反约束的异常,但它只发生在旧记录上。我的上一个更改是向名为KPIBusiness的父实体添加一个
mappedBy=kpi
-属性

我可以删除新创建的具有依赖项的父实体,但不能删除旧实体

KPIBusiness.java:

@Entity
public class KPIBusiness extends KPI {

    private Long businessProcessId;
    private String businessProcess;

    private Long eventId;
    private String event;

    @OneToMany(mappedBy="kpi", fetch = FetchType.EAGER, cascade=CascadeType.ALL)   
    private Set<Dependency> dependencies;
}
例外情况:

原因:org.h2.jdbc.jdbcsql异常:Referentielle Integrität verletzt:“FKSW30595DULXL90POB2K9KT3i: PUBLIC.kbibusiness\u DEPENDENCIES外键(DEPENDENCIES\u DID) 参考公共依赖关系(DID)(33)” 引用完整性约束冲突:“FKSW30595DULXL90POB2K9KT3i:PUBLIC.kBibusiness_依赖项” 键(DEPENDENCIES_DID)引用PUBLIC.DEPENDENCIES(DID)(33)”;SQL 声明: 从依赖项中删除did=?[23503-196]

我使用的代码是:

repository.delete(currentKPI);
repository.flush();
我现在正在考虑使用此代码:

currentKPI.setDependencies(new HashSet<Dependency>());
currentKPI = repository.save(currentKPI);
repository.flush();//HACK delete at first try
repository.delete(currentKPI);
repository.flush();

EmployeeEntity.java

@Entity
@Table(name = "Employee")
public class EmployeeEntity implements Serializable
{
    private static final long serialVersionUID = -1798070786993154676L;
    @Id
    @Column(name = "ID", unique = true, nullable = false)
    private Integer           employeeId;
    @Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100)
    private String            firstName;
    @Column(name = "LAST_NAME", unique = false, nullable = false, length = 100)
    private String            lastName;

    @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name="EMPLOYEE_ID")
    private Set<AccountEntity> accounts;

    //Getters and Setters Ommited
}
@Entity
@Table(name = "Account")
public class AccountEntity implements Serializable
{
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "ID", unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Integer           accountId;
    @Column(name = "ACC_NO", unique = false, nullable = false, length = 100)
    private String            accountNumber;

    @OneToOne (mappedBy="accounts",  fetch = FetchType.LAZY)
    private EmployeeEntity employee;

}
查看上面EmployeeEntity.java源代码中的粗体行。它定义了“cascade=CascadeType.ALL”,本质上意味着EmployeeEntity上发生的任何更改也必须级联到AccountEntity。若保存员工,则所有关联的帐户也将保存到数据库中。如果删除员工,则与该员工关联的所有帐户也将被删除。很简单

但如果我们只想级联保存操作,而不想级联删除操作呢。然后我们需要使用下面的代码清楚地指定它

@OneToMany(cascade=CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinColumn(name="EMPLOYEE_ID")
private Set<AccountEntity> accounts;
@OneToMany(cascade=CascadeType.PERSIST,fetch=FetchType.LAZY)
@JoinColumn(name=“EMPLOYEE\u ID”)
私人账户;
现在,只有在使用employee实例调用save()或persist()方法时,才会持久化帐户。若在会话中调用任何其他方法,其效果将不会影响/级联到帐户

JPA级联类型

Java持久性体系结构支持的级联类型如下:

  • CascadeType.PERSIST:表示save()或PERSIST()操作 级联到相关实体
  • CascadeType.MERGE:表示在 拥有的实体被合并
  • CascadeType.REFRESH:对REFRESH()执行相同的操作 手术
  • CascadeType.REMOVE:删除与关联的所有相关实体 删除所属实体时,此设置无效
  • CascadeType.DETACH:如果是“手动”,则分离所有相关实体 发生“分离”
  • CascadeType.ALL:是上述所有级联的缩写 行动

  • 您的级联是指从父级(
    kbibusiness
    )到子级(
    Dependency
    )。它不会以另一种方式工作。您的
    依赖项将不会(神奇地)从包含它的任何集合中删除

    备选案文1:

    KPIBusiness
    中删除
    依赖项
    ,然后将其删除。请在下面查找示例代码:

    // start a transaction
    Dependency dependencyToBeDeleted;
    KPIBusiness kpiBusiness;
    ...
    kpiBusiness.getDependencies().remove(dependencyToBeDeleted);
    dependencyRepository.remove(dependencyToBeDeleted);
    // commit the transaction
    
    备选案文2:

    使用
    删除=true
    ()扩展
    集合的
    @OneToMany
    注释。然后,从
    kbibusiness
    中的集合中删除
    依赖项就足够了,JPA将在不再引用该依赖项时自动将其从数据库中删除


    确保您完全了解删除级联和删除的用法。最好是得到一个错误,而不是JPA默默地删除你从未打算删除的东西

    如果不设置级联(可能为All?),则无法删除,因为外键引用了要删除的行。在父OneToMany语句中有一个
    cascade=CascadeType.All
    。@OneToMany(mappedBy=“kpi”,fetch=FetchType.EAGER,cascade=CascadeType.REMOVE)我还没有dependencyRepository,所以会选择选项2,这只是一个示例。它与
    entityManager
    一样工作。不管怎样,DependencyRepository最终会使用entityManager。我似乎在Dependencies中既有一个名为ID的联接列,也有一个名为
    kbibusiness\u Dependencies
    的表。后一个表似乎保存了提取的依赖项,而id列保存了大量未删除的垃圾行。我应该改变什么,以便数据库只以一种方式表示关系?我应该删除JoinColumn吗?我删除了数据库,以便在不使用
    KPIBUSINESS\u DEPENDENCIES
    表的情况下重新创建它
    @OneToMany(cascade=CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinColumn(name="EMPLOYEE_ID")
    private Set<AccountEntity> accounts;
    
    // start a transaction
    Dependency dependencyToBeDeleted;
    KPIBusiness kpiBusiness;
    ...
    kpiBusiness.getDependencies().remove(dependencyToBeDeleted);
    dependencyRepository.remove(dependencyToBeDeleted);
    // commit the transaction