My problem is that i have a class TM_TemporalExtent that defines a property of type TM_Primitive (an abstract class).
When i set this property to a concrete TM_GeometricPrimitive (that extends TM_Primitive), and save-then-retrieve the TM_TemporalExtent instance form hibernate, the extent property is not of TM_GeometricPrimitive!
the getclass().toString() is
class it.terranova.metadata.iso19115.helpers.temporalschema.TM_Primitive$$EnhancerByCGLIB$$22b6c9fa
so when i cast to TM_GeometricPrimitive the code throws a ClassCastException! Cast to TM_Primitive obviously works well...
The strange is:
1) In other classes i have other properties that are collections of abstract classes (mapped as idbag): in this properties i don't have the same problems!
2) If i define TM_Primitive as concrete class the problem persist!
I think that the problem is in management of many-to-one relations of polymorphic classes: any suggestions?
Hibernate version: 3.1.3
Mapping documents:
<class name="it.terranova.metadata.iso19115.extent.EX_TemporalExtent"
table="EX_TemporalExtent">
<id name="id">
<generator class="native"/>
</id>
<many-to-one name="extent" cascade="all" class="it.terranova.metadata.iso19115.helpers.temporalschema.TM_Primitive" />
</class>
<class name="it.terranova.metadata.iso19115.helpers.temporalschema.TM_Primitive"
table="TM_Primitive">
<id name="id">
<generator class="native"/>
</id>
</class>
<joined-subclass name="it.terranova.metadata.iso19115.helpers.temporalschema.TM_GeometricPrimitive" extends="it.terranova.metadata.iso19115.helpers.temporalschema.TM_Primitive" table="TM_GeometricPrimitive">
<key column="SUBCLASS_ID" />
<property name="startDate" type="timestamp" />
<property name="endDate" type="timestamp"/>
</joined-subclass>
Code between sessionFactory.openSession() and session.close():
Date now = Calendar.getInstance().getTime();
TM_GeometricPrimitive geometricPrimitive = new TM_GeometricPrimitive();
geometricPrimitive.setStartDate(now);
geometricPrimitive.setEndDate(now);
extent.setExtent(geometricPrimitive);
session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
session.save(extent);
session.getTransaction().commit();
session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
List query = session.createQuery("from EX_TemporalExtent").list();
EX_TemporalExtent newext = (EX_TemporalExtent)query.get(query.size() - 1);
assertNotNull(newext);
TM_Primitive extent2 = newext.getExtent();
assertTrue(extent2 instanceof TM_Primitive);
assertTrue(extent2 instanceof TM_GeometricPrimitive); // ERROR HERE!
Full stack trace of any exception that occurs:
junit.framework.AssertionFailedError
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.assertTrue(Assert.java:20)
at junit.framework.Assert.assertTrue(Assert.java:27)
at it.terranova.metadata.tests.iso19115.extent.TemporalExtentTest.testPersistence(TemporalExtentTest.java:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
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:478)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Name and version of the database you are using:
Oracle9i
PostgreSQL 8.1
HSQLDB last version
The generated SQL (show_sql=true):
Hibernate:
select
hibernate_sequence.nextval
from
dual
Hibernate:
select
hibernate_sequence.nextval
from
dual
Hibernate:
/* insert it.terranova.metadata.iso19115.helpers.temporalschema.TM_GeometricPrimitive
*/ insert
into
TM_Primitive
(id)
values
(?)
Hibernate:
/* insert it.terranova.metadata.iso19115.helpers.temporalschema.TM_GeometricPrimitive
*/ insert
into
TM_GeometricPrimitive
(startDate, endDate, SUBCLASS_ID)
values
(?, ?, ?)
Hibernate:
/* insert it.terranova.metadata.iso19115.extent.EX_TemporalExtent
*/ insert
into
EX_TemporalExtent
(extent, id)
values
(?, ?)
Hibernate:
/*
from
EX_TemporalExtent */ select
ex_tempora0_.id as id52_,
ex_tempora0_.extent as extent52_
from
EX_TemporalExtent ex_tempora0_
|