我为Dependency实体获得了违反约束的异常,但它只发生在旧记录上。我的最后一项更改是将mappedBy=kpi
- 属性添加到名为KPIBusiness的父实体。
我可以删除新创建的具有依赖关系但不包含旧实体的父实体。
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;
}
Dependency.java
@Entity
@Table(name="dependencies")
public class Dependency {
@Id
@GeneratedValue
private Long did;
public Long getDid() {
return did;
}
public void setDid(Long did) {
this.did = did;
}
private AlertConstants.TRIGGER kpiType;
private Long kpiId;
@JsonIgnore
@ManyToOne
@JoinColumn(name="id", nullable=false)
private KPIBusiness kpi;
}
例外:
引起:org.h2.jdbc.JdbcSQLException:ReferentielleIntegrität verletzt:“FKSKW30595DULXL90POB2K9KT3I: PUBLIC.KPIBUSINESS_DEPENDENCIES FOREIGN KEY(DEPENDENCIES_DID) 参考文献PUBLIC.DEPENDENCIES(DID)(33)“ 参照完整性约束违规:“FKSKW30595DULXL90POB2K9KT3I:PUBLIC.KPIBUSINESS_DEPENDENCIES FOREIGN KEY(DEPENDENCIES_DID)REFERENCES PUBLIC.DEPENDENCIES(DID)(33)“; SQL 声明: 从依赖项中删除do =? [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();
然而,似乎currentKPI.setDependencies(dependencies);
根本不更新依赖项。我使用此代码尝试更改依赖项:
Set<Dependency> dependencies = new HashSet<Dependency>();
for(RemoteKPINames kpi : tcsDependencies.getValue()) {
Dependency dependency = new Dependency();
dependency.setKpiId(kpi.getId());
dependency.setKpiType(kpi.getType());
dependency.setKpi(data);
dependencies.add(dependency);
}
log.info("Setting dependencies in data object #={}", dependencies.size());
data.setDependencies(dependencies);
答案 0 :(得分:1)
<强> 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
}
<强> AccountEntity.java 强>
@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;
现在,只有在使用员工实例调用save()或persist()方法时,才会保留帐户。如果在会话中调用任何其他方法,则其效果不会影响/级联到帐户。
JPA级联类型
Java Persistence Architecture支持的级联类型如下:
答案 1 :(得分:1)
您的级联用于从父级(KPIBusiness
)到子级(Dependency
)。它不会以其他方式工作。您的Dependency
无法(神奇地)从包含它的任何集合中删除。
选项1:
从Dependency
中删除KPIBusiness
并删除它。请在下面找到示例代码:
// start a transaction
Dependency dependencyToBeDeleted;
KPIBusiness kpiBusiness;
...
kpiBusiness.getDependencies().remove(dependencyToBeDeleted);
dependencyRepository.remove(dependencyToBeDeleted);
// commit the transaction
选项2:
使用@OneToMany
(Example)扩展Set<Dependencies>
的{{1}}注释。然后,它足以从orphanRemoval=true
中的集合中删除Dependency
,并且当JPA不再被引用时,它将自动将其从数据库中删除。
确保您完全了解 DELETE级联和 orphanRemoval 的用法。得到错误总是更好,而不是JPA默默地删除你从未打算删除的东西。