Reputation: 1359
Hi I have models like this :
public class Person extends Model {
...
@OneToMany(orphanRemoval = true, mappedBy = "person")
@Cascade({ CascadeType.ALL })
public List<Contact> infos = new ArrayList<Contact>();
}
public class Contact extends Model {
...
@ManyToOne(optional = false)
public Person person;
}
And I have a method in my controller like this :
public static void savePerson(Person person) {
person.save();
renderJSON(person);
}
My issue is that when I try to save a person with savePerson() I have this error (only if my list of Person isn't empty) :
PersistenceException occured : org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: models.Person.infos
I don't understand the error message because it appears if the list was previously empty or not.
Upvotes: 3
Views: 2687
Reputation: 9774
I had a very similar problem today.
The problem is that you can't just assign a new Collection to the 'infos' List, because then Hibernate gets confused. Play does this automatically when you use Person as a parameter in the controller. To solve this you need to modify the getters and setters for 'infos' so that it won't instantiate a new Collection / List.
This is the simplest solution I've found so far:
public class Person extends Model {
// ...
public List<Contact> getInfos() {
if (infos == null) infos = new ArrayList<Contact>();
return infos;
}
public void setInfos(List<Contact> newInfos) {
// Set new List while keeping the same reference
getInfos().clear();
if (newInfos != null) {
this.infos.addAll(newInfos);
}
}
// ...
}
And then in your controller:
public static void savePerson(Person person) {
person.merge();
person.save();
renderJSON(person);
}
Upvotes: 1