网上有大量关于此异常的问题和答案,但没有一个能解决我的问题。我有两个非常简单的实体 - 一个是类别,另一个是项目。类别与项目有一对多关系。我对插入语句没有任何问题。但是当我尝试删除 Category 时,由于外键约束("com.microsoft.sqlserver.jdbc.SQLServerException:DELETE 语句与 REFERENCE 约束"FK_CATEGORY"冲突,休眠会抛出"org.hibernate.exception.ConstraintViolationException: 无法执行语句"异常"。冲突发生在数据库"商店",表"dbo"中。项目",列"CATEGORY_ID"。因此,显然级联注释不起作用。我在这里错过了什么?
这是我的代码的样子:
int rows = em.createQuery("delete from CATEGORY where id = :id")
.setParameter("id", id)
.executeUpdate();
类别实体
@Entity
@Table(name = "CATEGORY")
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private int id;
@Column(name = "NAME")
@Size(max = 50)
private String name;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "category", cascade = CascadeType.ALL)
private Set<Item> items = new HashSet<>();
......//Getters and Setter
项目实体
@Entity
@Table(name = "ITEM")
public class Item {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private int id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CATEGORY_ID")
private Category category;
@Column(name = "NAME")
@Size(max = 150)
private String name;
....//Getters and Setters
}
要删除数据,您需要使用事务。
您可以使用用户事务:
UserTransaction utx = entityManager.getTransaction();
try {
utx.begin();
businessLogic();
utx.commit();
} catch(Exception ex) {
utx.rollback();
throw ex;
}
或春季@Transactional
@Transactional
public void businessLogic() {
... use entity manager inside a transaction ...
}
事实证明,Cascade 属性对 JPQL 不起作用,因为 JPA 不支持级联删除(此时(。如果你想让 JPQL 工作,需要将级联烘焙到模式中。这意味着删除外键约束并添加级联删除约束。否则,将引发外键约束异常。如果不想将级联烘焙到架构中,另一个选项是对每个对象使用休眠删除方法。