1

こんにちは、

Hibernate(バージョン3)を使用してdb(Oracle DB)から最初の100の従業員レコードを表示する単純なJ2EEアプリケーションがあります。すべてのテーブルには約 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)があります)、ポジション (id、名前) および Employee_Position_Office (employee_id、position_id、office_id) を db に格納します。そして、バッチサイズにいくつか問題があります。4つのSQLリクエスト(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 ?)

そして、batch-size を 100 を超える数に変更しても、何も変わりません。これは良いことです。

しかし、(これらのリクエストの後) Hibernate は Office 読み込みのリクエストを生成しますが、いくつか問題があります。お見せしましょう: 私の最初の 100 人の従業員は 397 のオフィス (ランダムに生成) で働いており、Hibernate は次の場合に 1 つのリクエストでそれらを読み込みます。バッチサイズが 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 未満または 397 を超える) を設定すると、Hibernate は同じ「ボディ」で他の「テール」を持ついくつかの sql-request を生成します。たとえば、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>

休止状態の cfg:

<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