I am trying to test if we could migrate a legacy application to use Hibernate for all dataaccess operations. The problem is that the DB schema is not strictly relational. There is a table containing properties which is associated to other tables using generated keys (not foreign keys).
An excerpt of the DB schema is available at:
When I try to load the code, I always get either a ClassCastException (with logging enabled) or IllegalArgumentException with logging disabled.
Details and mapping are given below.
Hibernate version: 3.2.2ga
Mapping documents:
Code:
<hibernate-mapping package="hibernatetest.beans" schema="TEST">
<!-- ... Adapter and Supplier removed for brevity ... -->
<class name="Property" table="PROPERTIES">
<composite-id>
<key-property name="propCd" column="PROP_CD" type="string"/>
<key-property name="propAssocTyp" column="PROP_ASSOC_TYP" type="string"/>
<key-property name="propAssocVal" column="PROP_ASSOC_VAL" type="string"/>
</composite-id>
<property name="propVal" column="PROP_VAL" type="string"/>
</class>
<class name="SupplierAdapter" table="SUPPLR_ADAPTER">
<composite-id>
<key-property name="supplierCategCd" column="SUPPLIER_CATEG_CD" type="string"/>
<key-property name="supplierCd" column="SUPPLIER_CD" type="string"/>
<key-property name="adapterId" column="ADAPTER_ID" type="long"/>
</composite-id>
<property name="isDefault" column="IS_DEFAULT" type="yes_no"/>
<property name="supplierAdapterCd" insert="false" update="false" type="string">
<formula>
(SELECT AD.ADAPTER_NM || ':' || TRIM(SUPPLIER_CD)
FROM TEST.ADAPTER AD
WHERE AD.ADAPTER_ID = ADAPTER_ID)
</formula>
</property>
<set name="properties" table="PROPERTIES" where="PROP_ASSOC_TYP = 'SUPP_AD'" fetch="subselect" cascade="all">
<key column="PROP_ASSOC_VAL" property-ref="supplierAdapterCd" />
<one-to-many class="Property"/>
</set>
</class>
Code between sessionFactory.openSession() and session.close():Code:
List<SupplierAdapter> supplierAdapters = session.createQuery("from SupplierAdapter").list();
// Iterate
for (SupplierAdapter supplierAdapter : supplierAdapters) {
supplierAdapter.getAdapter();
supplierAdapter.getSupplier();
Set<Property> properties = supplierAdapter.getProperties();
if (null != properties) {
for (Property property : properties) {
property.getPropCd();
}
}
}
Full stack trace of any exception that occurs:
With logging
Quote:
Exception in thread "main" java.lang.ClassCastException: java.lang.String
at org.hibernate.type.ComponentType.toLoggableString(ComponentType.java:377)
at org.hibernate.pretty.MessageHelper.collectionInfoString(MessageHelper.java:284)
at org.hibernate.engine.CollectionLoadContext.getLoadingCollection(CollectionLoadContext.java:141)
at org.hibernate.type.CollectionType.getCollection(CollectionType.java:534)
at org.hibernate.type.CollectionType.resolveKey(CollectionType.java:346)
at org.hibernate.type.CollectionType.resolve(CollectionType.java:340)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:116)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:842)
at org.hibernate.loader.Loader.doQuery(Loader.java:717)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.doList(Loader.java:2211)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2095)
at org.hibernate.loader.Loader.list(Loader.java:2090)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:375)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
at hibernatetest.TestMain.main(TestMain.java:35)
With logging set to ErrorQuote:
05:23:54,531 [main] ERROR [org.hibernate.property.BasicPropertyAccessor] - IllegalArgumentException in class: hibernatetest.beans.SupplierAdapter, getter method of property: supplierCategCd
Exception in thread "main" org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of hibernatetest.beans.SupplierAdapter.supplierCategCd
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:171)
at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:64)
at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValues(AbstractComponentTuplizer.java:70)
at org.hibernate.tuple.component.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:83)
at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:353)
at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:184)
at org.hibernate.engine.EntityKey.generateHashCode(EntityKey.java:104)
at org.hibernate.engine.EntityKey.<init>(EntityKey.java:48)
at org.hibernate.persister.collection.AbstractCollectionPersister.getSubselectInitializer(AbstractCollectionPersister.java:594)
at org.hibernate.persister.collection.AbstractCollectionPersister.getAppropriateInitializer(AbstractCollectionPersister.java:574)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:344)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:163)
at hibernatetest.TestMain.main(TestMain.java:43)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:145)
... 16 more
Name and version of the database you are using:DB2 UDB version 9.1
The generated SQL (show_sql=true):Quote:
05:21:23,500 [main] DEBUG [org.hibernate.SQL] - select supplierad0_.SUPPLIER_CATEG_CD as SUPPLIER1_3_, supplierad0_.SUPPLIER_CD as SUPPLIER2_3_, supplierad0_.ADAPTER_ID as ADAPTER3_3_, supplierad0_.IS_DEFAULT as IS4_3_,
(SELECT AD.ADAPTER_NM || ':' || TRIM(supplierad0_.SUPPLIER_CD)
FROM TEST.ADAPTER AD
WHERE AD.ADAPTER_ID = supplierad0_.ADAPTER_ID)
as formula0_ from TEST.SUPPLR_ADAPTER supplierad0_
Hibernate: select supplierad0_.SUPPLIER_CATEG_CD as SUPPLIER1_3_, supplierad0_.SUPPLIER_CD as SUPPLIER2_3_, supplierad0_.ADAPTER_ID as ADAPTER3_3_, supplierad0_.IS_DEFAULT as IS4_3_,
(SELECT AD.ADAPTER_NM || ':' || TRIM(supplierad0_.SUPPLIER_CD)
FROM TEST.ADAPTER AD
WHERE AD.ADAPTER_ID = supplierad0_.ADAPTER_ID)
as formula0_ from TEST.SUPPLR_ADAPTER supplierad0_
Debug level Hibernate log excerpt: