JPA 和 Hibernate Cascade DELETE OneToMany 不起作用

Gre*_*egg 6 spring hibernate jpa cascade spring-boot

我一直在阅读一篇又一篇文章,一篇又一篇文章,试图在最新的 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;

}
Run Code Online (Sandbox Code Playgroud)

不起作用:

@Entity
public class Brand {

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

}
Run Code Online (Sandbox Code Playgroud)

除了删除TaxRates之前删除之外还有什么工作Brand吗?

我的测试是这样的:

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

错误供参考:

引起:org.h2.jdbc.JdbcSQLException:参照完整性约束违规:“FKC4BCIKI2WSPO6WVGPO3XLA2Y9:PUBLIC.TAX_RATE FOREIGN KEY(BRAND_ID)REFERENCES PUBLIC.BRAND(ID)(1)”;SQL 语句:从品牌中删除 id=? [23503-192]

更新:修改我的brandService.deleteAll()方法以执行以下操作:

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

仍然不起作用。

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

Vla*_*cea 11

我想您想看看@OnDelete生成 DDL 级级联删除的注释。

如果您使用自动模式生成(例如 hbm2ddl),这将添加ON DELETE CASCADEFOREIGN KEY定义中。但是,使用Flyway 几乎总是比 hbm2ddl更好的选择

您的映射变为:

@OneToMany(mappedBy = "brand", orphanRemoval = true, fetch = FetchType.LAZY)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonManagedReference("brand-tax-rate")
private List<TaxRate> taxRates;
Run Code Online (Sandbox Code Playgroud)