Hi,
I have a simple model where a Parent has a unidirectional ManyToMany relation with a Child and the child has a unidirectional OneToMany relation with a Toy. The ManyToMany relation is (obviously) via a join table, which has a surrogate PK that is used for the CollectionID, and the OneToMany relation is via a foreign key in the table of the many side of that relation.
In my example data I have 1 parent who has 1 child, who has two toys.
An em.find with the ID of the parent however returns a parent with -2- (identical) children instead of 1.
I don't understand why this is happening. Via the CollectionId annotation, Hibernate should know that there is only 1 record in the join table between the Parent and Child, so that the Parent only has one Child.
I tried with both Hibernate 3.3.1 (JBoss AS 5.1) and 3.5.5 (JBoss AS 6m5).
These are my entities:
Code:
@Entity
public class Parent {
private Long id;
private String name;
private List<Child> children;
@Id
@GeneratedValue(strategy = IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable (
name = "parent_child",
joinColumns = @JoinColumn(name = "parent_id"),
inverseJoinColumns = @JoinColumn(name = "child_id")
)
@CollectionId(
columns = @Column(name = "id"),
type = @Type(type = "string"),
generator = "identity"
)
public List<Child> getChildren() {
return children;
}
public void setChildren(List<Child> children) {
this.children = children;
}
}
Code:
@Entity
public class Child {
private Long id;
private String name;
private List<Toy> toys;
@Id
@GeneratedValue(strategy = IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "child_id")
public List<Toy> getToys() {
return toys;
}
public void setToys(List<Toy> toys) {
this.toys = toys;
}
}
Code:
@Entity
public class Toy {
private Long id;
private String name;
@Id
@GeneratedValue(strategy = IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The SQL query that Hibernate generates:
Code:
select
parent0_.id as id0_2_,
parent0_.name as name0_2_,
children1_.parent_id as parent1_4_,
child2_.id as child2_4_,
children1_.id as id4_,
child2_.id as id2_0_,
child2_.name as name2_0_,
toys3_.child_id as child3_5_,
toys3_.id as id5_,
toys3_.id as id1_1_,
toys3_.name as name1_1_
from
Parent parent0_
left outer join
parent_child children1_
on parent0_.id=children1_.parent_id
left outer join
Child child2_
on children1_.child_id=child2_.id
left outer join
Toy toys3_
on child2_.id=toys3_.child_id
where
parent0_.id=?
When I run this query manually on my DB (PostgreSQL 8.4) it returns two rows, one for each different toy. I expect Hibernate to read the object graph from these two rows and give me back 1 parent, with 1 child with 2 toys.
If any additional information is needed I'll be happy to provide it.