I am using Hibernate 3 and Oracle 9.
I am working with legacy tables that cannot be changed. Many of these tables do not have a primary key. I tried working with a composite-id of all of the columns in the table, but ran into problems with duplicate rows and null values. Finally, I came up with the solution of using ROWID as a primary key. Everything was working smoothly.
I was using this code to generate all Classification objects with the given serial number. No problems.
Code:
Criteria criteria = session.createCriteria(Classification.class);
criteria.add(Expression.eq("serialNo", serialNo));
list = criteria.list();
Then, it came time to optimize. I read somewhere that HQL queries in the mapping could increase performance due to caching. I tried this out on one of my classes that does not use ROWID and it did increase the speed. So, I changed the above code to
Code:
Query query = session.getNamedQuery("Classification.getBySerialNo");
query.setLong("serialNo", serialNo);
list = query.list();
to go with the HQL in Classification.hbm.xml
Code:
<hibernate-mapping
<class name="Classification" table="XML_AP_CLASSIFICATION" mutable="false">
<cache usage="read-only"/>
<id column="ROWID" name="id">
<generator class="native"/>
</id>
<property column="SERIAL_NO" name="serialNo" type="long"/>
<property column="INTERNATIONAL_CODE_TOTAL_NO" name="internationalCodeTotalNo" type="string"/>
<property column="US_CODE_TOTAL_NO" name="usCodeTotalNo" type="string"/>
<property column="INTERNATIONAL_CODE" name="internationalCode" type="string"/>
<property column="US_CODE" name="usCode" type="string"/>
<property column="STATUS_DATE" name="statusDate" type="com.nameprotect.tm.hibernate.us.dao.util.StringDateType"/>
<property column="FIRST_USE_ANYWHERE_DATE" name="firstUseAnywhereDate" type="com.nameprotect.tm.hibernate.us.dao.util.StringDateType"/>
<property column="FIRST_USE_IN_COMMERCE_DATE" name="firstUseInCommerceDate" type="com.nameprotect.tm.hibernate.us.dao.util.StringDateType"/>
<property column="PRIMARY_CODE" name="primaryCode" type="string"/>
<property column="STATUS_CODE" name="statusCode" type="com.nameprotect.tm.hibernate.us.dao.code.ClassStatusCode$UserType" />
</class>
<query name="Classification.getBySerialNo"><![CDATA[
from Classification where serialNo = :serialNo
]]></query>
</hibernate-mapping>
This caused problems with the ROWID. With the Criteria way, hibernate was generating this SQL:
select this_.ROWID as
ROWID0_, this_.SERIAL_NO as SERIAL2_6_0_, ....
but with the HQL way, it is generating this SQL:
select classifica0_.ROWID as
ROWID, classifica0_.SERIAL_NO as SERIAL2_4_, ....
This causes a problem because ROWID is special for Oracle and cannot be used as the alias. I have narrowed the problem down to org.hibernate.mapping.Column.getAlias().
Does anyone have any suggestions or workarounds?