I have a persistent class (Claim) that has a one-to-one relationship with another class (ClaimCommunicationActivity).
The code works fine, and when I look at the generated SQL, I get a select from CLAIM with a left outer join on COMMACTVTY.
My problem is that COMMACTVTY is defined as a view, and because of the view implementation, using it in a left outer join is really slow. (In DB terms, a full view materialization happens and it affects the performance in really big ways).
So I thought, rather than use FetchMode of JOIN, I'd change it to FetchMode of SELECT. That results in queries that the database is much happier with, but when there are a lot of Claims returned from my initial query, there are a lot of follow-up SELECT statements (which affect performance).
So I hoped to solve this new problem using a batch-size of, say, 100 to get 100 items at a time. However, it seems like Hibernate completely ignores batch-size on a one-to-one relationship and always reverts to issuing one select for every Claim key.
I redefined my mapping file from a one-to-one to a many-to-one and added a not-found="ignore", and once I did that, the batch-size started to be used. Is it just true that Hibernate ignores batch-size when the relationship is a one-to-one relationship?
Thanks,
BC
Hibernate version: 3.0.5
Mapping documents:
Code:
<class
name="com.example.claims.model.Claim"
table="CL01_CLAIM"
dynamic-update="false"
dynamic-insert="false"
select-before-update="false"
optimistic-lock="version"
mutable="false">
<composite-id
name="key"
class="com.example.claims.model.ClaimKey" >
<key-property
name="companyNumber"
type="java.lang.Integer"
column="COMPANY" />
<key-property
name="claimNumber"
type="com.example.claims.hibernate.EncodableNumberUserType"
column="CLAIMNO" />
</composite-id>
...
<one-to-one
name="communicationActivity"
class="com.example.claims.model.ClaimCommunicationActivity"
fetch="join"
lazy="true" />
</class>
</hibernate-mapping>
and
Code:
<hibernate-mapping>
<class
name="com.example.claims.model.ClaimCommunicationActivity"
table="CL01_COMMACTVTY"
dynamic-update="false"
dynamic-insert="false"
select-before-update="false"
optimistic-lock="version"
mutable="false"
batch-size="500">
<composite-id
name="key"
class="com.example.claims.model.ClaimKey" >
<key-property
name="companyNumber"
type="java.lang.Integer"
column="COMPANY" />
<key-property
name="claimNumber"
type="com.example.claims.hibernate.EncodableNumberUserType"
column="CLAIMNO" />
</composite-id>
<property
name="latestCommunicationDate"
type="com.example.claims.hibernate.IntegerDateUserType"
update="true"
insert="true"
access="property"
column="LSTCOMMDATE"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
public Claim[] getClaims(final Integer[] claimNumbers) {
HibernateTemplate template = createReadOnlyHibernateTemplate();
return (Claim[]) template.execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Criteria criteria = session.createCriteria(Claim.class);
criteria.add(Restrictions.in("key.claimNumber",
Arrays.asList(claimNumbers)));
criteria.add(Restrictions.eq("key.companyNumber",
new Integer(1)));
List list = criteria.list();
return list.toArray(new Claim[list.size()]);
}
});
}
Name and version of the database you are using: DB2 for z/OS v. 7