I'm having some problems mapping inheritance using annotations. My base class is:
Code:
package prod.data.hibernate;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
@Entity()
@Inheritance(
strategy=InheritanceType.SINGLE_TABLE,
discriminatorType=DiscriminatorType.INTEGER,
discriminatorValue="-1"
)
@Table(name="Digital_Clip")
@DiscriminatorColumn(name="digital_clip_type_id")
public abstract class TestBaseClass {
private long id;
private Integer startTime;
private Integer stopTime;
protected TestBaseClass() {
id = -1;
}
@Id
@Column(name="digital_clip_id")
public long getId() {
return id;
}
protected void setId(long id) {
this.id = id;
}
public Integer getStartTime() {
return startTime;
}
public void setStartTime(Integer startTime) {
this.startTime = startTime;
}
public Integer getStopTime() {
return stopTime;
}
public void setStopTime(Integer stopTime) {
this.stopTime = stopTime;
}
}
and my subclass (one for this example) is:
Code:
package prod.data.hibernate;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
@Entity()
@Inheritance(
discriminatorValue="4"
)
public class TestSubClass extends TestBaseClass {
public TestSubClass() {
super();
// TODO Auto-generated constructor stub
}
}
I also have a JUnit test case:
Code:
package prod.data.hibernate;
import junit.framework.TestCase;
public class InheritanceTest extends TestCase {
public void testSelect() {
TestBaseClass test =
(TestBaseClass) HibernateUtil.currentSession()
.createQuery("select base from TestBaseClass base where base.id = 644")
.list().get(0);
System.out.println(test);
}
}
When I run the unit test with the following mapping document:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="prod.data.hibernate.TestBaseClass" table="Digital_Clip" discriminator-value="-1">
<id name="id" type="long" column="digital_clip_id" >
<generator class="native"/>
</id>
<discriminator column="digital_clip_type_id" type="integer" />
<property name="startTime" />
<property name="stopTime" />
<subclass name="prod.data.hibernate.TestSubClass" discriminator-value="4" />
</class>
</hibernate-mapping>
everything works fine, and I get an instance of the subclass as I would expect. However, when I try using the annotations in the class, I get the following stack trace:
Code:
org.hibernate.WrongClassException: Object with id: 644 was not of the specified subclass: prod.data.hibernate.TestBaseClass (Discriminator: 644)
at org.hibernate.loader.Loader.getInstanceClass(Loader.java:1445)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1276)
at org.hibernate.loader.Loader.getRow(Loader.java:1197)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:568)
at org.hibernate.loader.Loader.doQuery(Loader.java:689)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:223)
at org.hibernate.loader.Loader.doList(Loader.java:2147)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2026)
at org.hibernate.loader.Loader.list(Loader.java:2021)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:369)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:298)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1020)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:74)
at prod.data.hibernate.InheritanceTest.testSelect(InheritanceTest.java:10)
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 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 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)
Note that 644 is the ID of the class,
not the value of the discriminator. Also, I've noticed that the generated sql in the first case looks like this:
Code:
select
testbasecl0_.digital_clip_id as digital1_0_,
testbasecl0_.start_time as start3_0_,
testbasecl0_.stop_time as stop4_0_,
testbasecl0_.digital_clip_type_id as digital2_0_
from
Digital_Clip testbasecl0_
where
testbasecl0_.digital_clip_id=644
and in the second case, it looks like this:
Code:
select
testbasecl0_.digital_clip_id as digital1_0_,
testbasecl0_.stop_time as stop3_0_,
testbasecl0_.start_time as start4_0_
from
Digital_Clip testbasecl0_
where
testbasecl0_.digital_clip_id=644
Note that in the second case, the digital_clip_type_id is not being retrieved.
Any ideas as to what I'm doing wrong?
-Jack