I use hibernate 5.0.8 and spring data jpa 1.10.1
Given these entities
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
}
Model is the master, but multiple models can use the same configuration. The cascading on configuration in Model is required, because if I change anything in the Configuration, I want it to be applied in all Models using this Configuration
Now when I retrieve an existing Model with a Configuration that has settings, and save this Model, without applying any changes to the settings I get following exception
@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);
}
I get the following exception
A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: Configuration.settings
I suspect this has something to do with the settings being lazy loaded and hibernate trying to merge an empty list into the configuration.
What am I doing wrong?
The problem was being caused by using enableLazyInitialization from the hibernate-enhance-maven-plugin. I still have no idea why it was causing this error, but removing this plugin resolved the issue.
I used this plugin, because I wanted to lazy load a large String field in Model that I would cache in the application. I will now change it to a OneToOne relation that is fetched lazily.