1

你好,

我有一个简单的 J2EE 应用程序,它使用 Hibernate(版本 3)显示来自 db(Oracle DB)的前 100 条员工记录。所有的表都有大约 10000 条记录。有 Country(id, name), City(id, name, country_id), Address(id, address, city_id), Company(id, name), Office(id, company_id, address_id), Employee(id, name, address_id ), Position(id, name) 和 Employee_Position_Office(employee_id, position_id, office_id) 在数据库中。我对批量大小有一些问题。我需要在 4 个 sql-request(由 Hibernate 生成)中完成。让我们告诉你我有什么:

在我的类映射中,我设置了 batch-size=100,Hibernate 为 Employee、OfficePosition 和 Address 加载创建了 3 个 sql-request,看:

select * from ( select employee0_.ID as ID6_, employee0_.NAME as NAME6_,     employee0_.ADDRESS as ADDRESS6_ from EMPLOYEE employee0_ ) where rownum <= ?

select officeposi0_.EMPLOYEE_ID as EMPLOYEE1_6_1_, officeposi0_.POSITION_ID as POSITION2_1_, officeposi0_.OFFICE_ID as OFFICE3_1_, position1_.ID as ID5_0_, position1_.NAME as NAME5_0_ from EMPLOYEE_POSITION_OFFICE officeposi0_ inner join POSITION position1_ on officeposi0_.POSITION_ID=position1_.ID where officeposi0_.EMPLOYEE_ID in (100x ?)

select address0_.ID as ID2_2_, address0_.ADDRESS as ADDRESS2_2_, address0_.CITY_ID as CITY3_2_2_, city1_.ID as ID1_0_, city1_.NAME as NAME1_0_, city1_.COUNTRY_ID as COUNTRY3_1_0_, country2_.ID as ID0_1_, country2_.NAME as NAME0_1_ from ADDRESS address0_ left outer join CITY city1_ on address0_.CITY_ID=city1_.ID left outer join COUNTRY country2_ on city1_.COUNTRY_ID=country2_.ID where address0_.ID in (100x ?)

如果我将批量大小更改为超过 100 的数量,则没有任何变化 - 这很好。

但随后(在这些请求之后)Hibernate 生成 Office 加载请求,我遇到了一些问题,让我们向您展示:我的 100 名第一批员工在 397 个办公室工作(随机生成),Hibernate 应该在批量大小超过 397,当我将批量大小设置为 397 时它工作正常(在 1 个 sql 请求中),

select office0_.ID as ID4_4_, office0_.COMPANY_ID as COMPANY2_4_4_, office0_.ADDRESS_ID as ADDRESS3_4_4_,  (SELECT COUNT(*) FROM EMPLOYEE_POSITION_OFFICE
            E WHERE
            E.OFFICE_ID=office0_.ID)
         as formula0_4_, company1_.ID as ID3_0_, company1_.NAME as NAME3_0_, address2_.ID as ID2_1_, address2_.ADDRESS as ADDRESS2_1_, address2_.CITY_ID as CITY3_2_1_, city3_.ID as ID1_2_, city3_.NAME as NAME1_2_, city3_.COUNTRY_ID as COUNTRY3_1_2_, country4_.ID as ID0_3_, country4_.NAME as NAME0_3_ from OFFICE office0_ left outer join COMPANY company1_ on office0_.COMPANY_ID=company1_.ID left outer join ADDRESS address2_ on office0_.ADDRESS_ID=address2_.ID left outer join CITY city3_ on address2_.CITY_ID=city3_.ID left outer join COUNTRY country4_ on city3_.COUNTRY_ID=country4_.ID where office0_.ID in (397x ?)

但是当我设置任何其他数字(小于或大于 397)时,Hibernate 会生成几个具有相同“body”但其他“tails”的 sql 请求。例如,当 batch-size = 400 时有结果。

...in (200x ?)
...in (100x ?)
...in (50x ?)
...in (25x ?)
...in (12x ?)
...in (10x ?)    

请告诉我我做错了什么,可以解决吗?谢谢。

我的映射:

    <class name="---.Address" table="ADDRESS"
    batch-size="100">
        <id name="id" type="long">
            <column name="ID" />
            <generator class="increment" />
    </id>
    <property name="address" type="java.lang.String">
        <column name="ADDRESS" />
    </property>
    <many-to-one name="city" class="---.City"
        fetch="join">
        <column name="CITY_ID" />
    </many-to-one>
</class>

<class name="---.City" table="CITY">
    <id name="id" type="long">
        <column name="ID" />
        <generator class="increment" />
    </id>
    <property name="name" type="java.lang.String">
        <column name="NAME" />
    </property>
    <many-to-one name="country" class="---.Country"
        fetch="join">
        <column name="COUNTRY_ID" />
    </many-to-one>
</class>

<class name="---.Company" table="COMPANY">
    <id name="id" type="long">
        <column name="ID" />
        <generator class="increment" />
    </id>
    <property name="name" type="java.lang.String">
        <column name="NAME" />
    </property>
</class>

<class name="---.Country" table="COUNTRY">
    <id name="id" type="long">
        <column name="ID" />
        <generator class="increment" />
    </id>
    <property name="name" type="java.lang.String">
        <column name="NAME" />
    </property>
</class>

<class name="---.Employee" table="EMPLOYEE"
    batch-size="100">
    <id name="id" type="long">
        <column name="ID" />
        <generator class="increment" />
    </id>
    <property name="name" type="java.lang.String">
        <column name="NAME" />
    </property>
    <many-to-one name="address" class="---.Address"
        fetch="join">
        <column name="ADDRESS" unique="true" />
    </many-to-one>
    <map name="officePositions" table="EMPLOYEE_POSITION_OFFICE" lazy="false"
        fetch="join" batch-size="100">
        <key>
            <column name="EMPLOYEE_ID"></column>
        </key>
        <map-key-many-to-many class="---.Office">
            <column name="OFFICE_ID">
            </column>
        </map-key-many-to-many>
        <many-to-many column="POSITION_ID"
            class="---.Position" />
    </map>
</class>

<class name="---.Office" table="OFFICE"
    batch-size="400">
    <id name="id" type="long">
        <column name="ID" />
        <generator class="increment" />
    </id>
    <many-to-one name="company" class=---.Company"
        fetch="join">
        <column name="COMPANY_ID" />
    </many-to-one>
    <many-to-one name="address" class="---.Address"
        fetch="join">
        <column name="ADDRESS_ID" />
    </many-to-one>
    <property name="collegues">
            <formula> 
SELECT COUNT(*) FROM EMPLOYEE_POSITION_OFFICE
            E WHERE
            E.OFFICE_ID=ID
        </formula>
    </property>
</class>


<class name="---.Position" table="POSITION">
    <id name="id" type="long">
        <column name="ID" />
        <generator class="increment" />
    </id>
    <property name="name" type="java.lang.String">
        <column name="NAME" />
    </property>
</class>

休眠配置:

<hibernate-configuration>
<session-factory>
    <property name="connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>
    <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
    <property name="connection.username">---</property>
    <property name="connection.password">----</property>
    <property name="connection.pool_size">10</property>
    <property name="current_session_context_class">thread</property>
    <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
    <property name="hibernate.use_sql_comments">false</property>
    <property name="hibernate.format_sql">false</property>
    <property name="hibernate.show_sql">true</property>


    <mapping resource="---/Country.hbm.xml" />
    <mapping resource="---/City.hbm.xml" />
    <mapping resource="---/Address.hbm.xml" />
    <mapping resource="---/Company.hbm.xml" />
    <mapping resource="---/Office.hbm.xml" />
    <mapping resource="---/Position.hbm.xml" />
    <mapping resource="---/Employee.hbm.xml" />
</session-factory>

4

0 回答 0