Reputation: 4136
Seems it is a standard problem, but searching for solution have no success. I have parent class Person
with two childen sets:
class Person {
@OneToMany(mappedBy = "person", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
Set<Dog> dogs;
@OneToMany(mappedBy = "person", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
Set<Cat> cats;
}
child class Cat
(class Dog
looks same):
class Cat {
private String name;
@ManyToOne(targetEntity = Person.class, fetch = FetchType.EAGER)
@JoinColumn(name = "PERSON_ID")
public Person getPerson() {
return person;
}
}
What is the problem. When I try to retrieve all Persons
, which Cat
name equals 'Fritz', Hibernate create joined query on table Cat
, which name is 'Fritz'. Everything looks fine, but when I expand retrieved Person
(in Idea debugger), it contains only single instance of Cat
(with name 'Fritz'), despite Person
can have multiple Cats
. Simultaneously with expanding, Hibernate make other request to Dog
table and retrieve all items linked with this Person
, and this field populates correctly. How can I force Hibernate to populate field Cat
with all items, not only with joined item?
P.S. I use Spring's HibernateTemplate session.get(), not HQL.
EDIT 1. Generated query (the second part executes only when I expand retrieved Person
in debugger):
Hibernate:
select
person.PERSON_ID,
person.PERSON_NAME,
cat.CAT_ID,
cat.NAME,
from
PERSON person
left outer join
CAT cat
on person.PERSON_ID=cat.PERSON_ID
where
cat.NAME='FRITZ'
Hibernate:
select
dog.DOG_ID,
dog.NAME,
dog.PERSON_ID
from
DOG dog
where
dog.DOG_ID=1
EDIT 2. Seems my issue is a former Hibernate bug . But i'm still need help. My Hibernate version is 4.3.
Upvotes: 1
Views: 873
Reputation: 4136
After day of furious efforts, i've got it. The problem was in LEFT_OUTER_JOIN
. Replaced it by INNER_JOIN
, and all my nested collections become fully filled. For more detailed explanation, see https://hibernate.atlassian.net/browse/HHH-2049
Upvotes: 1
Reputation: 148965
I am not really confident in using a debugger to see how hibernate actually maps association. It uses special collections that it populates on-demand, because populating a collection causes an extra request and Hibernate tries to give a good mix between simplicity and performance.
So when you ask for *the person owning Pussicat`, Hibernate only does the query on table Person unless you eagerly load child table, an will only do the queries on child tables if you list the cats and dogs of that person in code an not in debugger.
And you know you cannot eagerly load all association. If you did, any simply query could load all the database ...
IMHO when you say Hibernate did not populate cats Set, it is only because in the debugger the set is not initially null nor empty and so the debugger does not ask hibernate to issue the query. But if you asked in the code for the list of cats, you would get it correctly.
Upvotes: 3