我一直在阅读帖子后文章和文章试图在最新的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;
}
除了在删除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);
}
}
参考错误:
引起: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) );
}
仍然无效。
更新2:通过测试似乎只是一个问题。 Cascade似乎可以正常运行应用程序。
答案 0 :(得分:4)
我想你想看看生成DDL级别级联删除的@OnDelete
注释。
如果您正在使用自动模式生成(例如hbm2ddl),则会向ON DELETE CASCADE
定义添加FOREIGN KEY
。但是,使用Flyway is almost always a better choice而不是hbm2ddl。
您的映射变为:
@OneToMany(mappedBy = "brand", orphanRemoval = true, fetch = FetchType.LAZY)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonManagedReference("brand-tax-rate")
private List<TaxRate> taxRates;