I have found several questions about this, but none with a complete explaintation of the problem, and how to debug it - the answers are all anecdotal.
The problem is that in a Play 1.2.4 JPA test, I'm getting this exception when I save() a model:
org.hibernate.HibernateException: Found two representations of same collection: models.Position.projects
I would like to know:
- Is there a documentation of this problem in general, unrelated to Play? The issue is in hibernate, yet a lot of the Google results on this are within Play apps.
- What are some basic best practices to avoid this problem?
- Is it caused by Play? Or something I'm doing wrong?
- How to resolve in my specific case?
Here is a reproduction of the problem on github. I have four entities:
@Entity public class Person extends Model { public String name; @OneToMany(cascade = CascadeType.ALL) public List<Position> positions; } @Entity public class Position extends Model { public Position(){} public Position(Company companies) { this.companies = companies; this.projects = new ArrayList<Project>(); } @OneToOne public Company companies; @ManyToOne public Person person; @OneToMany public List<Project> projects; } @Entity public class Company extends Model { public String name; } @Entity public class Project extends Model { public Project(){} public Project(String field, String status){ this.theField = field; this.status = status; } @ManyToOne public Position position; public String theField; public String status; } And my persistence code:
Company facebook = new Company(); facebook.name = "Facebook"; facebook.save(); Company twitter = new Company(); twitter.name = "Twitter"; twitter.save(); Person joe = new Person(); joe.name = "Joe"; joe.save(); joe.positions = new ArrayList<Position>(); Position joeAtFacebook = new Position(facebook); joeAtFacebook.projects.add(new Project("Stream", "Architect")); joeAtFacebook.projects.add(new Project("Messages", "Lead QA")); joe.positions.add(joeAtFacebook); Position joeAtTwitter = new Position(twitter); joeAtTwitter.projects.add(new Project("Steal stuff from Facebook", "CEO")); joe.positions.add(joeAtTwitter); joe.save(); BTW, I've tried adding the Play associations module as one person suggested, and it does't seem to help.
I see that indeed that tables that are created are duplicate in a sense:
I have both a person_position table and a position table, where both contain similar fields: person_position contains a Person_id and positions_id, while the position table contain id (meaning position id), person_id, and companies_id. So I understand some kind of unintended redundancy is created by my model definition, but I don't really understand how to solve it.
I thought this might be related to bi-directional mappings, but here is a branch where the model is uni-directional (I removed some back-references) - and the problem still occurs.