I have two entityclasses (person and organization) that I use to track groups of individuals. These are mapped to each other using a many-to-many relationship with organization being the "owning" side.
When I create a "person" and add it to multiple organizations then persist each organization (using entitymanager.merge(organizationobject), the same person is represented in multiple rows in the database (each with a unique "personid" but all other properties of the person are the same).
I read the FAQ and Hibernate docs, and I understand that I need to implement hashCode() and equals() to get around the problem of the same object being represented in multiple collections. However, even after I've implemented these two methods, I am still getting duplicates in the person table when I persist (with cascade) two organizations that share the same person. If anyone has any advice on how to fix this problem, I'd really appreciate it!
What I do is basically:
Code:
Person a = new Person('Jack', 'Smith');
Organization b = new Organization('Nonprofit');
Organization c = new Organization('Commercial');
b.addPerson(a);
c.addPerson(a);
//Note that the addPerson method implements a reciprocal a.addOrganization(b) call to add the organization to the person's organizations collection.
EntityManager em = Persistence.createEntityManagerFactory().createEntityManager();
em.getTransaction().begin();
em.merge(b);
em.merge(c);
em.getTransaction().commit();
em.close();
The relevant mapping is as follows:
Code:
@Entity
public class Person {
@Id
@SequenceGenerator(name = "seq", sequenceName = "seq")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
protected Long personid;
@ManyToMany(mappedBy = "people", cascade = CascadeType.ALL)
protected Collection<Organizations> organizations;
}
public class Organization {
@Id
@SequenceGenerator(name = "seq", sequenceName = "seq")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
protected Long organizationid;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name="person_collections",
joinColumns=
@JoinColumn(name="organizationid", referencedColumnName="organizationid"),
inverseJoinColumns=
@JoinColumn(name="personid", referencedColumnName="personid"))
private Collection<Person> people
}
Side note: Actually, the entity classes are physiology related, but I thought a more common example would be easier to follow.
Hibernate version: 3.2 GA
Name and version of the database you are using:
PostgreSQL