JPA和Hibernate级联DELETE onetmany不起作用



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

在删除Brand之前,除了删除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_RATE外键(brand_id)引用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) );
}

仍然不能工作。

UPDATE 2:只有通过测试才会出现问题。

我想你应该看看@OnDelete注释,它生成一个ddl级的级联删除。

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

你的映射变成:

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

最新更新