Read the rules before posting!
http://www.hibernate.org/ForumMailingli ... AskForHelp
Hibernate version:Hibernate 3 rc 1
Mapping documents:<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping (View Source for full doctype...)>
- <hibernate-mapping default-cascade="none" default-access="property" default-lazy="true" auto-import="true">
- <!-- Category Inheritance Tree-->
- <class name="com.aca.model.Category" table="categories" mutable="true" abstract="false" polymorphism="implicit" dynamic-update="false" dynamic-insert="false" select-before-update="false" optimistic-lock="version">
- <composite-id name="primaryKey" class="com.aca.model.pk.IdVersionPK" unsaved-value="undefined">
<key-property name="id" />
<key-property name="version" />
</composite-id>
<discriminator column="ItemType" type="string" not-null="true" force="false" insert="true" />
- <!-- Properties-->
- <property name="uniqueId" not-null="false" unique="false" update="true" insert="true" optimistic-lock="true" lazy="false">
<column name="uniqueId" not-null="true" />
</property>
<property name="description" not-null="false" unique="false" update="true" insert="true" optimistic-lock="true" lazy="false" />
- <!-- SubClasses -->
- <subclass name="com.aca.model.Item" dynamic-update="false" dynamic-insert="false" select-before-update="false" abstract="false">
- <join table="CategoryDetails" fetch="join" inverse="false" optional="false">
- <key on-delete="noaction">
<column name="id" />
<column name="version" />
</key>
- <!-- We tried with lazy=false,true and fetch=select,join but these changes didn't solve the problem -->
<many-to-one name="parentCategory" property-ref="uniqueId" column="parentUniqueId" lazy="false" not-null="false" unique="false" update="true" insert="true" optimistic-lock="true" />
<property name="otherFeature" column="otherFeature" not-null="false" unique="false" update="true" insert="true" optimistic-lock="true" lazy="false" />
</join>
<subclass name="com.aca.model.Application" discriminator-value="AP" dynamic-update="false" dynamic-insert="false" select-before-update="false" abstract="false" />
<subclass name="com.aca.model.Service" discriminator-value="SV" dynamic-update="false" dynamic-insert="false" select-before-update="false" abstract="false" />
</subclass>
</class>
- <!-- End of Category Inheritance Tree --> </hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
application.getUniqueId()
Full stack trace of any exception that occurs:[INFO] DefaultLoadEventListener - -Error performing load command <org.hibernate.PropertyAccessException: exception getting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info) getter of com.aca.model.pk.IDVersionPK.?>org.hibernate.PropertyAccessException: exception getting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info) getter of be.ing.smkb.model.pk.IDVersionPK.?
at org.hibernate.tuple.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:42)
at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:257)
at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:158)
at org.hibernate.engine.EntityKey.getHashCode(EntityKey.java:68)
at org.hibernate.engine.EntityKey.<init>(EntityKey.java:41)
at org.hibernate.type.ManyToOneType.scheduleBatchLoad(ManyToOneType.java:85)
at org.hibernate.type.ManyToOneType.hydrate(ManyToOneType.java:66)
at org.hibernate.persister.entity.BasicEntityPersister.hydrate(BasicEntityPersister.java:1663)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:877)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:833)
at org.hibernate.loader.Loader.getRow(Loader.java:746)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:290)
at org.hibernate.loader.Loader.doQuery(Loader.java:384)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:203)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1255)
at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:139)
at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:124)
at org.hibernate.persister.entity.BasicEntityPersister.load(BasicEntityPersister.java:2453)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:387)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:368)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:166)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:140)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:119)
at org.hibernate.impl.SessionImpl.immediateLoad(SessionImpl.java:571)
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:59)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:80)
at org.hibernate.proxy.CGLIBLazyInitializer.intercept(CGLIBLazyInitializer.java:133)
at com.aca.model.ConfigurationItem$$EnhancerByCGLIB$$e02ebb9e.getUniqueId(<generated>)
at com.aca.test.ConfigurationItemTest.testFindCIByUniqueId(ConfigurationItemTest.java:313)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:41)
at java.lang.reflect.Method.invoke(Method.java:386)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:392)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:276)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:167)
Caused by: java.lang.ClassCastException: java.lang.Long
at be.ing.smkb.model.pk.IDVersionPK$$BulkBeanByCGLIB$$43f49ae7.getPropertyValues(<generated>)
at net.sf.cglib.beans.BulkBean.getPropertyValues(BulkBean.java:48)
at org.hibernate.tuple.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:39)
... 43 more
Name and version of the database you are using:Oracle 9.0.2
The generated SQL (show_sql=true):
Debug level Hibernate log excerpt:debug
Quote:
General description of the key problem
Domain
I simplified our domain model and all other info to show you the core of the problem.
In the domain model there is a class Category, which is subclassed by Item, which in its turn is subclassed by Application and Service. Item has a parentCategory and otherFeature as additional features compared to Category. Most applications have a service, which can be consulted by means of the method “Category getParent()”
Tables
This domain is mapped on an existing database with tables Category and CategoryDetails. The table Category contains the fields uniqueId, id, version, itemType and description. CategoryDetails is linked to Category by means of the composite key id and version (this composite key is contained in a separate primary-key-class IdVersionPK as described in the manual, which implements the equals and hashcode functions) CategoryDetails contains the fields id and version, parentUniqueId and otherFeature. ParentUniqueId points to the uniqueId in the table Category. (kind of double-up)
Mapping
I want to use Hibernate 3 since the subclass tag can contain the join tag in this version.
In the join tag there is a many-to-one relationship since a parentService can be the parent of many applications and also the field otherFeature. In the many-to-one relationship property-ref is used to map the parentUniqueId column to uniqueId property of the Category Class. The field itemType is used as a discriminator. Value “AP” represents an application while value “SV” represents a service.
Problem Description
A PropertyAccessException is thrown with reference to IdVersionPK. After debugging, it seems that in the getPropertyValues() method of the PojoComponentTuplizer there is a mix up. This happens at the moment that the object to be retrieved from the query has been created and most attributes already have been assigned their value. However, at the many-to-one relation a ClassCastException occurs. The parentUniqueId value is fetched correctly from the database but then Hibernate tries to assign this Long value to the IdVersionPK Primary Key class. When the parentUniqueId column is null the object can be retrieved, otherwise the Exception occurs. Is this a mapping configuration error on our site, or is it an error in hibernate? Why does Hibernate try to assign the Long value to the IDVersionPK as we defined uniqueId as the property-ref value. The strange thing is that this only occurs on a load. If we assign a parentCategory to a Service then the parentUniqueId field is stored correctly in the database table (as a Long).
Code:
package com.aca.model;
import java.io.Serializable;
import java.util.Date;
import com.aca.model.pk.IdVersionPK;
public class Category{
// Unique ID in the Database (Incremented by sequence)
private long uniqueId;
private IVersionPK primaryKey;
// Type of Category (Application, ProcessGroup, etc...)
private String itemType;
// A description of the what this category is/does.
private String description;
public Category(){
}
public void setUniqueId(long uniqueId){
this.uniqueId = uniqueId;
}
public long getUniqueId(){
return uniqueId;
}
public void setDescription(String description){
this.description = description;
}
public String getDescription(){
return description;
}
public String getItemType() {
return itemType;
}
public void setItemType(String string) {
itemType = string;
}
public IdVersionPK getPrimaryKey() {
return primaryKey;
}
public void setPrimaryKey(IdVersionPK versionPK) {
primaryKey = versionPK;
}
}
Code:
package com.aca.model.pk;
import java.io.Serializable;
public class IdVersionPK implements Serializable{
private long id;
private int version;
public IdVersionPK() {
super();
id = -1;
version = -1;
}
public IdVersionPK(long id, int version){
super();
this.id = id;
this.version = version;
}
public boolean equals(Object obj) {
try{
IdVersionPK idvPair = (IdVersionPK) obj;
if (( idvPair.id == id ) && ( idvPair.version == version )){
return true;
}
}catch(ClassCastException cce){
return false;
}
return false;
}
public int hashCode() {
return (int) id + version;
}
public long getId() {
return id;
}
public int getVersion() {
return version;
}
public void setId(long l) {
id = l;
}
public void setVersion(int i) {
version = i;
}
}
Code:
package com.aca.model;
import java.util.HashSet;
import java.util.Set;
public class Item extends Category {
protected Integer otherFeature;
// A reference to the parent (in case of an application this is the service)
protected Category parentCategory;
public ConfigurationItem() {
super();
parentCategory = new Category();
}
public Integer getOtherFeature() {
return otherFeature;
}
public Category getParentCategory() {
return parentCategory;
}
public void setOtherFeature(Integer i) {
otherFeature = i;
}
public void setParentCategory(Category parentCategory) {
this.parentCategory = parentCategory;
}
}
Code:
package com.aca.model;
public class Application extends Item {
public Application() {
super();
}
}