【问题标题】:Hibernate throwing ConstraintViolationException when executing delete statement执行删除语句时休眠抛出ConstraintViolationException
【发布时间】:2020-03-19 15:13:55
【问题描述】:

网上有很多关于这个例外的问题和答案,但没有一个能解决我的问题。我有两个非常简单的实体——一个是类别,另一个是项目。类别与项目具有一对多的关系。我对插入语句没有任何问题。但是当我尝试删除 Category 时,由于外键约束,hibernate 抛出“org.hibernate.exception.ConstraintViolationException:无法执行语句”异常(“com.microsoft.sqlserver.jdbc.SQLServerException:DELETE 语句与 REFERENCE 约束冲突“FK_CATEGORY”。数据库“shop”、表“dbo.ITEM”、列“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

}

【问题讨论】:

  • 不使用原生查询,尝试使用JPA删除功能删除
  • @Viswa 这不是本机查询,而是 JPQL 查询。 em.remove 会更简洁,但会执行相同的 JPA 逻辑。问题是级联。
  • @chrylis 谷歌搜索后,我的理解是 JPA 规范不包括级联删除。所以执行 delete JPQL 语句会导致 FK 约束异常。解决方案是像 Viswa 所说的那样使用 hibernate remove

标签: java spring hibernate


【解决方案1】:

删除数据需要使用Transaction。

您可以使用 UserTransaction:

UserTransaction utx = entityManager.getTransaction(); 

try { 
    utx.begin(); 
    businessLogic();
    utx.commit(); 
} catch(Exception ex) { 
    utx.rollback(); 
    throw ex; 
} 

或Spring @Transactional

@Transactional
public void businessLogic() {
... use entity manager inside a transaction ...
}

【讨论】:

  • 感谢您的回复。但我确实有事务注释。如果我不这样做,那将是一个不同的例外,而不是我现在拥有的外键约束。
【解决方案2】:

事实证明,级联属性对 JPQL 无效,因为 JPA 不支持级联删除(此时)。如果您希望 JPQL 工作,则需要将级联纳入模式。这意味着删除外键约束并添加级联删除约束。否则会抛出外键约束异常。如果您不想将级联烘焙到模式中,另一种选择是对每个对象使用 hibernate remove 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-28
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    相关资源
    最近更新 更多