orphanRemoval вызывает ошибку в загруженной коллекции
Я использую hibernate 5.0.8 и данные весны jpa 1.10.1
Учитывая эти лица
class Model {
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
@JoinColumn(nullable = false)
private Configuration configuration;
//more fields and methods
}
class Configuration {
@OneToMany(mappedBy = "configuration", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Setting> settings = new ArrayList<>();
//more fields and methods
//settings is never assigned again - I use settings.add(...) and settings.clear()
}
class Setting {
@ManyToOne
@JoinColumn(nullable = false)
private Configuration configuration;
//more fields and methods
}
Модель является основной, но несколько моделей могут использовать одну и ту же конфигурацию. Требуется каскадное конфигурирование в Модели, потому что, если я что-то изменяю в Конфигурации, я хочу, чтобы это применялось во всех Моделях, использующих эту Конфигурацию.
Теперь, когда я получаю существующую модель с конфигурацией, в которой есть настройки, и сохраняю эту модель, не применяя никаких изменений в настройках, я получаю следующее исключение
@Transactional
public void doSomething() {
Model model = modelRepository.findOne(0);
//change something in the model, but no changes are made in its configuration
//or do nothing
modelRepository.save(model);
}
Я получаю следующее исключение
A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: Configuration.settings
Я подозреваю, что это как-то связано с тем, что настройки загружаются лениво и в спящем режиме, пытаясь объединить пустой список с конфигурацией.
Что я делаю неправильно?
2 ответа
Проблема была вызвана использованием enableLazyInitialization из плагина hibernate-gain-maven-plugin. Я до сих пор не знаю, почему это вызвало эту ошибку, но удаление этого плагина решило проблему.
Я использовал этот плагин, потому что я хотел лениво загрузить большое поле String в Model, которое я бы кешировал в приложении. Теперь я изменю его на отношение OneToOne, которое выбирается лениво.
Проверьте получатели и установщики объектов, которые вы пытаетесь очистить как сироты при разыменовании:
Попробуйте и используйте:
public void setChildren(Set<Child> aSet) {
//this.child= aSet; //Results in this issue
//change to
this.child.clear();
if (aSet != null) {
this.child.addAll(aSet);
} }