你好,
我有一个简单的 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>