Hi, all:
I want to get rid of the N+1 select problem, all I can found in documentation is to use "left join fetch". But in my case, it will return redundant parent records. How do I resolve this? Your answer is highly appreciated! Thanks!
Hibernate version:
3.1.3
Mapping documents:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping>
<!-- table created by: CREATE TABLE KEYWORDS ( ID IDENTITY, NAME VARCHAR(25) ); -->
<class name="ihub.hibernate.Person"
table="person"> <id name="id"
type="integer"
column="PERSON_ID">
<generator class="native"/>
</id>
<property name="name"
column="NAME"
unique="false"
/>
<set name="emails" table="email">
<key column="PERSON_ID"/>
<one-to-many class="ihub.hibernate.Email"/>
</set>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping>
<!-- table created by: CREATE TABLE KEYWORDS ( ID IDENTITY, NAME VARCHAR(25) ); -->
<class name="ihub.hibernate.Email"
table="email"> <id name="id"
type="integer"
column="EMAIL_ID">
<generator class="native"/>
</id>
<property name="personID"
column="PERSON_ID"
unique="false"
/>
<property name="email"
column="EMAIL_ADDR"
unique="true"
/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
List<Person> persons = session.createQuery(
"from Person p left join fetch p.emails where name like 'Lili%'")
.list();
for (Person p : persons) {
out.println("--- found person: " + p.getName());
for (Email e : p.getEmails()) {
out.println("----- personal email: " + e.getEmail());
}
}
Full stack trace of any exception that occurs:
--- found person: Lili
----- personal email:
lili3@xxx.com
----- personal email:
lili2@xxx.com
----- personal email:
lili1@xxx.com
--- found person: Lili
----- personal email:
lili3@xxx.com
----- personal email:
lili2@xxx.com
----- personal email:
lili1@xxx.com
--- found person: Lili
----- personal email:
lili3@xxx.com
----- personal email:
lili2@xxx.com
----- personal email:
lili1@xxx.com
--- found person: Lili2
----- personal email:
lili4@xxx.com
----- personal email:
lili5@xxx.com
--- found person: Lili2
----- personal email:
lili4@xxx.com
----- personal email:
lili5@xxx.com
Name and version of the database you are using:
SQL Server 2000
The generated SQL (show_sql=true):
select person0_.PERSON_ID as PERSON1_1_0_, emails1_.EMAIL_ID as EMAIL1_0_1_, person0_.NAME as NAME1_0_, emails1_.PERSON_ID as PERSON2_0_1_, emails1_.EMAIL_ADDR as EMAIL3_0_1_, emails1_.PERSON_ID as PERSON2_0__, emails1_.EMAIL_ID as EMAIL1_0__ from person person0_ left outer join email emails1_ on person0_.PERSON_ID=emails1_.PERSON_ID where name like 'Lili%'
Debug level Hibernate log excerpt: