We need to get back a collection of Widgets, where each widget can contain zero or more Fidgets. Our problem is that whenever we run from Widget
, Hibernate generates one SQL query for each Fidget on each Widget. So If I have one Widget with 19 Fidgets, Hibernate runs 20 SQL queries! I would have expected only two queries: one for the Widget and one for the Fidgets.
We have SQL Server 2005 and WebLogic 10g.
My relevant Spring Configuration:
<jee:jndi-lookup id="dataSourceA" jndi-name="jdbc/dataSourceA" />
<bean id="sessionFactoryA" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceA" />
<property name="mappingResources">
<list>
<value>com/mycompany/database/Widget.hbm.xml</value>
<value>com/mycompany/database/Fidget.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.query.factory_class=org.hibernate.hql.classic.ClassicQueryTranslatorFactory
hibernate.dialect=org.hibernate.dialect.SQLServerDialect
hibernate.show_sql=true
</value>
</property>
</bean>
<bean id="transactionManagerA" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactoryA" />
</bean>
My Widget.hbm.xml:
<class name="Widget" package="com.mycompany.database">
<id name="id" column="ID" type="integer">
<generator class="identity" />
</id>
...
<set name="fidgets" table="Fidget" lazy="false">
<key column="WidgetID" />
<one-to-many class="Fidget" />
</set>
</class>
My Fidget.hbm.xml:
<class name="Fidget" package="com.mycompany.database">
<id name="id" column="ID" type="integer">
<generator class="identity" />
</id>
...
<many-to-one name="widget" column="WidgetID" class="Widget" lazy="false" />
</class>
The following SQL is generated by Hibernate for a Widget with four Fidgets and a Widget with six Fidgets:
select fidget_.Col1, fidget_.Col2, ... from Fidget fidget_ where fidget_.WidgetID 开发者_Go百科= 7
select fidget_.Col1, fidget_.Col2, ... from Fidget fidget_ where fidget_.WidgetID = 7
select fidget_.Col1, fidget_.Col2, ... from Fidget fidget_ where fidget_.WidgetID = 7
select fidget_.Col1, fidget_.Col2, ... from Fidget fidget_ where fidget_.WidgetID = 7
select fidget_.Col1, fidget_.Col2, ... from Fidget fidget_ where fidget_.WidgetID = 8
select fidget_.Col1, fidget_.Col2, ... from Fidget fidget_ where fidget_.WidgetID = 8
select fidget_.Col1, fidget_.Col2, ... from Fidget fidget_ where fidget_.WidgetID = 8
select fidget_.Col1, fidget_.Col2, ... from Fidget fidget_ where fidget_.WidgetID = 8
select fidget_.Col1, fidget_.Col2, ... from Fidget fidget_ where fidget_.WidgetID = 8
select fidget_.Col1, fidget_.Col2, ... from Fidget fidget_ where fidget_.WidgetID = 8
Enable batch fetching in the Hibernate configuration to reduce the number of queries, or execute a query that will load the Widgets and their Fidgets:
select w from Widget w left join fetch w.fidgets where ...
This is also well described in the reference documentation, which is a great source of information.
精彩评论