Hi,
Over the last few days something strange has been happening on our QA server. I have a mapping with subclasses set up with discriminators:
Code:
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.test.model" >
<class name="Transaction" table="trans" lazy="false" discriminator-value="UNKNOWN" >
<id name="id" type="long" unsaved-value="0">
<column name="id" not-null="true"/>
<generator class="native">
<param name="sequence">trans_id_seq</param>
</generator>
</id>
<discriminator type="string" force="true"/>
<version name="hbversion" type="integer" column="hbversion" unsaved-value="undefined"/>
<property name="state" type="string" length="100" not-null="true" />
<subclass name="CreditTransaction"
discriminator-value="CREDIT" lazy="false">
<many-to-one name="txn" column="txnid" class="com.test.CreditTxn"/>
</subclass>
<subclass name="DebitTransaction"
discriminator-value="DEBIT" lazy="false">
<many-to-one name="txn" column="txnid" class="com.test.DebitTxn"/>
</subclass>
</class>
</hibernate-mapping>
Previously this worked fine. However a few days ago I started seeing errors when attempting to load Transactions on our QA environment:
org.hibernate.WrongClassException: Object with id: 104503 was not of the specified subclass: com.test.model.Transaction (Discriminator: credit)
at org.hibernate.loader.Loader.getInstanceClass(Loader.java:1600)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1431)
at org.hibernate.loader.Loader.getRow(Loader.java:1355)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:611)
at org.hibernate.loader.Loader.doQuery(Loader.java:829)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.doList(Loader.java:2533)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
at org.hibernate.loader.Loader.list(Loader.java:2271)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:452)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1268)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
at org.hibernate.impl.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:890)
The QA environment is inserting lower case discriminators and failing to load them. However my local environment inserts upper case discriminators and succeeds to load them. My local server will fail to load any inserted by the QA server (i.e. those with lower case discriminators). I am pointing my local server at the same database as the QA server.
On both servers I see the discriminator in the SQL is being set as upper case:
2012-06-14 17:33:44,841 DEBUG [http-bio-/10.30.3.5-8080-exec-14] org.hibernate.SQL - insert into trans (hbversion, state, class) values (?, ?, 'CREDIT')
If I debug in Hibernate the discriminator values are stored in a map against the class. As far as I can tell the hbm file has always had them in upper case. If the lower case string is loaded from the database the map returns null (as the key is upper case). I can't see how this has ever worked but years of use prove that it has.
I'm using the following versions:
Hibernate: 3.6.5.Final
Database: SQL Server 10.50.1600.1
Driver: jTDS 1.2.5
As far as I'm aware both servers are running the same code with the same driver (I've tried swapping my local driver with the one on QA and vice versa and I still get the issue).
If anyone has run into this problem before or can shed any light on what might be causing it your help will be greatly appreciated as I'm pretty much out of ideas.
Thanks,
Sam