org.hibernate.exception.ConstraintViolationException with onetomany annotation in hibernate 在 hibernate 中使用 onetomany 注解时出现约束冲突异常。

11 浏览
0 Comments

org.hibernate.exception.ConstraintViolationException with onetomany annotation in hibernate 在 hibernate 中使用 onetomany 注解时出现约束冲突异常。

我刚开始探索Spring Boot和Hibernate,并面临一个我认为并不新的问题。然而,尽管有所有的建议,我仍然找不到解决我目前面临问题的方法。请问你们中的任何人能够指出我错在哪里吗?

以下是情景描述 -

我有一个Category类,每个Category类的实例可以有多个SubCategory类的实例。

我使用@OneToMany注解设置了它们之间的关系。然而,在尝试保存记录到数据库时,我遇到了org.hibernate.exception.ConstraintViolationException的问题,报告中说外键值不能为NULL。

请找到下面的类声明

Category.class

Category类

...

SubCategory.class

SubCategory类

...

ServiceImpl -

ServiceImpl实现类

...

不确定我错在哪里。

报告的异常具有以下堆栈跟踪 -

...

其中关键的一行是:Column 'category_id' cannot be null(列'category_id'不能为空)。

0
0 Comments

问题出现的原因是在保存子对象之前尝试保存父对象。解决方法是先保存父对象,然后保存子对象。具体实现如下:

categoryRepository.save(category);
Set subCategoryRec = category.getSubCategories();
if(subCategoryRec != null && subCategoryRec.size() > 0) {
    for(SubCategory rec: subCategoryRec) {
        subcategoryRepository.save(rec);  
    }
}

在执行以上代码后,记录会被保存在主对象和子对象中。然而,子对象中的外键仍然为NULL,没有引用到主对象。这里是否有什么遗漏的地方?

在你的服务类(public void save(Category category))中,当你传递category对象时,应该设置好所有属性。如果还没有设置,那么在保存之前设置subcategory的category属性为subCategory.setCategory(category)。

0
0 Comments

在Hibernate中使用@OneToMany注解时出现了org.hibernate.exception.ConstraintViolationException的问题。这个问题的产生原因是没有正确使用级联操作。

根据这里提供的解释,级联操作是指在进行一次操作(保存、更新或删除)后,决定是否对与之相关的其他实体进行相同的操作。因此,可以通过以下方式解决该问题:

@OneToMany(fetch = FetchType.EAGER, mappedBy = "category", cascade=CascadeType.PERSIST)
private Set SubCategories;

在上述代码中,我们使用了`cascade=CascadeType.PERSIST`来指定级联操作类型为持久化操作。如果需要在删除等操作中使用不同的级联行为,可以选择不同的级联类型。

Hibernate支持的级联类型包括:

- `CascadeType.PERSIST`:表示保存(save)或持久化(persist)操作会级联到相关实体。

- `CascadeType.MERGE`:表示合并(merge)操作会级联到相关实体。

- `CascadeType.REFRESH`:表示刷新(refresh)操作会级联到相关实体。

- `CascadeType.REMOVE`:表示删除操作时,会删除与之关联的所有实体。

- `CascadeType.DETACH`:表示手动分离时,会分离所有相关实体。

- `CascadeType.ALL`:是上述所有级联操作的简写。

更多级联类型的详细解释可以参考这里。

另外需要注意的是,调用`.save`方法并不会自动提交事务,如果需要手动提交事务,可以尝试使用`.saveAndFlush`方法。但是建议使用级联操作来处理该问题。

参考:Difference between save and saveAndFlush in Spring data jpa

0