Я читал пост после публикации и статьи после статьи, пытаясь получить каскадные удаления для работы с JPA/Hibernate в последней версии Spring Boot. Я читал, что вам нужно использовать каскады Hibernate, и я читал, что вы этого не делаете. Я читал, что они просто не работают, но, похоже, это смешанная сумка. Все, что я пробовал, не работает. Отношение является двунаправленным.JPA и Hibernate Cascade DELETE OneToMany не работает
не работает:
@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 ИНОСТРАННЫЙ КЛЮЧ (BRAND_ID) ССЫЛКИ PUBLIC.BRAND (ID) (1) "; SQL-оператор: удалить из бренда, где id =? [23503-192]
UPDATE: изменил мой brandService.deleteAll()
способ сделать следующее:
@Override
public void deleteAll() {
Iterable<Brand> iter = this.brandRepository.findAll();
iter.forEach(brand -> this.brandRepository.delete(brand));
}
все еще не работает.
ОБНОВЛЕНИЕ 2: Это может показаться проблемой с помощью тестов. Кажется, что Cascade работает нормально с приложением.
Что brandService.deleteAll() выглядит? Можете ли вы добавить код? –
'brandRepository.deleteAll()' это все, что он делает. Мои репозитории - все интерфейсы CrudRepository. – Gregg
Каков результат. Исключение? Если так, включите ведение журнала SQL, чтобы узнать, что происходит. –