当前位置: 首页 > 知识库问答 >
问题:

JPA和Hibernate级联删除OneToMany不起作用

严亦
2023-03-14

我一直在阅读一篇又一篇的帖子和文章,试图让级联删除在最新的Spring Boot版本中与JPA/Hibernate配合使用。我读过你必须使用Hibernate特定的级联,我读过你不需要。我读过它们就是不起作用,但它似乎是一个混合体。我尝试过的一切都不起作用。这种关系是双向的。

不工作:

@Entity
public class Brand {

    @OneToMany(mappedBy = "brand", orphanRemoval = true, fetch = FetchType.LAZY)
    @Cascade({CascadeType.DELETE})
    @JsonManagedReference("brand-tax-rate")
    private List<TaxRate> taxRates;

}

不工作:

@Entity
public class Brand {

    @OneToMany(mappedBy = "brand", cascade = CascadeType.REMOVE, orphanRemoval = true, fetch = FetchType.LAZY)
    @JsonManagedReference("brand-tax-rate")
    private List<TaxRate> taxRates;

}

在删除品牌之前,除了删除税率之外,还有什么其他方法有效吗?

我的测试如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {Application.class, SpringSecurityConfig.class})
@ActiveProfiles("test")
@Transactional
public class CascadeTests {

    @Autowired
    private BrandService brandService;

    @Autowired
    private TaxRateLoaderService taxRateLoaderService;

    @Autowired
    private TaxRateService taxRateService;

    @Autowired
    private TaxRateRepository taxRateRepository;

    @Autowired
    private BrandRepository brandRepository;

    @Test
    public void testCascadeWorks() throws Exception {

        taxRateLoaderService.loadData(null, 10);

        // if I uncomment this then I'm good
        // but shouldn't have to if cascade works
        //taxRateService.deleteAll();
        brandService.deleteAll();

        List<TaxRate> rates = Lists.newArrayList(taxRateRepository.findAll());
        List<Brand> brands = Lists.newArrayList(brandRepository.findAll());

        Assert.assertEquals(rates.size(), 0);
        Assert.assertEquals(brands.size(), 0);
    }
}

参考错误:

原因:org.h2.jdbc.JdbcSQLException:引用完整性约束违反:"FKC4BCIKI2WSPO6WVGPO3XLA2Y9: PUBLIC.TAX_RATEFOREIGN KEY(BRAND_ID)REFERENCES PUBLIC. BRAND(ID)(1)";SQL语句:从id=?[23503-192]的品牌中删除

更新:修改了我的品牌服务。deleteAll()方法执行以下操作:

@Override
public void deleteAll() {
    Iterable<Brand> iter = this.brandRepository.findAll();
    iter.forEach(brand -> this.brandRepository.delete(brand) );
}

仍然不起作用。

更新2:通过测试,这似乎只是一个问题。Cascade似乎可以在应用程序运行时正常工作。

共有1个答案

江向阳
2023-03-14

我想您应该看看生成DDL级级联删除的注释。

如果您使用的是自动模式生成(例如hbm2ddl),则这将在删除级联上向外键定义添加一个。然而,使用Flyway几乎总是比hbm2ddl更好的选择。

您的映射变成:

@OneToMany(mappedBy = "brand", orphanRemoval = true, fetch = FetchType.LAZY)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonManagedReference("brand-tax-rate")
private List<TaxRate> taxRates;
 类似资料:
  • 我无法使用Hibernate JPA嵌入使cascase删除在Java EE容器管理的应用程序中工作。我们将不胜感激。我有一个实体‘公司',与其他实体有四个任何关系。当测试应用程序(使用Arquillian框架)时,我无法使级联删除工作;公司实体被删除,删除后子实体仍然存在。我读到了这里:JPA和Hibernate Cascade DELETE OneToMany不起作用,这可能是一个测试问题,所

  • 我读过一些相关的问题,但它们和我的问题不完全一样。 我使用的是JPA Hibernate Spring,我想做一些我不确定是否仅通过配置就可以做到的事情。 我的域类具有或多或少复杂的关系。有许多元素与一个元素相关(就像是一棵树,许多元素是一个元素的子元素)。 类似的东西: 这样会得到一张桌子: 当我删除id=1的行时,我希望删除id=2和id=3的行(这可能是递归的,parent_id=2并且pa

  • 我有两个实体业务,由一个部门列表组成。 当我尝试删除一个业务实例时,我得到一个Mysql异常 无法删除或更新父行:外键约束失败(

  • 问题内容: 我对父实体和子实体之间的简单映射有疑问。一切正常,只有当我从集合中删除子记录时,才会删除它们。 父母: 孩子: 如果我现在从childs集合中删除and child,它不会从数据库中删除。我尝试取消引用,但这也不起作用。 实体在Web应用程序中使用,删除是Ajax请求的一部分。按下保存按钮时,我没有已删除子项的列表,因此我无法隐式删除它们。 问题答案: JPA的行为是正确的( 按照规范

  • 问题内容: 我一直在搞怪它并使用它搜索了大约4天,我对Hibernate注释如何与JPA注释一起工作感到疯狂。我有两个非常简单的实体: 学生 电话 我将整个代码粘贴到这里,以便您可以看到导入的来源。我认为问题就在那里。 重要提示 :我使用的是Hibernate Docs建议的 好!现在,我创建了一个包含两个电话号码的,并将其正确保存在数据库中。这将创建以下内容: 学生 学生电话 电话 问题来了。如

  • 我使用的是Hibernate的JPA实现。我有一个包含不同类型用户(私有、公共等)的用户表,user_type列指定用户的类型。 我有一个User类,它是一个表示User表的实体。我补充说 在我的用户类上创建了两个类,PrivateUser和PublicUser,它们都用相应的@DiscriminatorValue扩展了用户类。 如果我的解释不清楚,请让我知道。 提前致谢