如何让 Hibernate 在 WebLogic 10g 上对每个父/子关系执行不超过一个 SQL 查询?

发布于 2024-12-08 01:12:01 字数 3041 浏览 0 评论 0原文

我们需要取回 Widget 的集合,其中每个 widget 可以包含零个或多个 Fidget。我们的问题是,每当我们从 Widget 运行时,Hibernate 都会为每个 Widget 上的每个 Fidget 生成一个 SQL 查询。因此,如果我有一个带有 19 个 Fidgets 的 Widget,Hibernate 将运行 20 个 SQL 查询!我预计只有两个查询:一个针对 Widget,另一项针对 Fidgets。

我们有 SQL Server 2005 和 WebLogic 10g。

我的相关 Spring 配置:

<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>

我的 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>

我的 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>

Hibernate 为具有四个 Fidget 的 Widget 和一个具有六个 Fidget 的 Widget 生成以下 SQL:

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 = 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

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 = 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

若水微香 2024-12-15 01:12:01

启用批量获取 Hibernate 配置以减少查询数量,或执行将加载小部件及其 Fidgets 的查询:

select w from Widget w left join fetch w.fidgets where ...

这在 参考文档,这是一个很好的来源的信息。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文