Spring 3.1 Hibernate 4 exception for Inheritance [cannot be cast to org.hibernate.mapping.RootClass]

南楼画角 提交于 2019-11-26 11:24:23

问题


Hi I have just started using Spring , with Hibernate4 and maven. Basically my class hierarchy is HUmanMicroTask extends from MicroTask . In future there may be several other classes extending from MicroTask. I was trying to have a one table per concrete class which is the simplest way to get up and running with spring3 and hibernate 4. However when i run my code. I keep getting the following exception

13:11:52,260 ERROR TestContextManager:324 - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@6ef137d] to prepare test instance [HumanMicroTaskBaseHibernateTest@52c05d3b]
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name \'sessionFactory\' defined in class path resource [database-config.xml]: Invocation of init method failed; nested exception is java.lang.ClassCastException: org.hibernate.mapping.UnionSubclass cannot be cast to org.hibernate.mapping.RootClass
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:103)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
    at org.springframework.test.context.support.DelegatingSmartContextLoader.loadContext(DelegatingSmartContextLoader.java:228)
    at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:124)
    at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:148)
    ... 24 more
Caused by: java.lang.ClassCastException: org.hibernate.mapping.UnionSubclass cannot be cast to org.hibernate.mapping.RootClass
    at org.hibernate.cfg.annotations.PropertyBinder.bind(PropertyBinder.java:212)
    at org.hibernate.cfg.annotations.PropertyBinder.makePropertyValueAndBind(PropertyBinder.java:203)
    at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:2013)
    at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:768)
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:687)
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3431)
    at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3385)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1337)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1727)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1778)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:184)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:314)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
    ... 38 more

Although I have seen quite a few forums, I am unabelt o decide on where I am making the mistake. My MicroTask class looks as follows :

@Entity
@Table(name = \"MICROTASK\")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class MicroTask {
    @Id
    @GeneratedValue(generator = \"system-uuid\")
    @GenericGenerator(name = \"system-uuid\", strategy = \"uuid\")
    @Column(name = \"MICROTASKID\")
    private String microTaskId;
    @Column(name = \"CREATIONDATE\")
    private Date creationDate;
    @Column(name = \"DESCRIPTION\")
    private String description;

    public Date getCreationDate() {
        return creationDate;
    }
//More Getters and setters 

My HumanMicroTask Class looks as follows :

    @Entity
    @Table(name = \"HUMANMICROTASK\")
    @AttributeOverrides({
        @AttributeOverride(name=\"microTaskId\", column=@Column(name=\"MICROTASKID\")),
        @AttributeOverride(name=\"creationDate\", column=@Column(name=\"CREATIONDATE\")),
        @AttributeOverride(name=\"description\", column=@Column(name=\"DESCRIPTION\"))
    })
    public class HumanMicroTask extends MicroTask {


        @Column(name = \"TITLE\")
        private String title;
        @Column(name = \"CHANNEL\")
        private String channel;
        @Id
        @Column(name = \"HMTID\")
        private String humanMicroTaskid;

        public String getId() {
            return humanMicroTaskid;
        }
//More Getters and setters

And my config.xml looks as follows :

<beans xmlns=\"http://www.springframework.org/schema/beans\"
    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:p=\"http://www.springframework.org/schema/p\"
    xmlns:context=\"http://www.springframework.org/schema/context\" xmlns:tx=\"http://www.springframework.org/schema/tx\"
    xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        \">

    <bean id=\"dataSource\" class=\"com.mchange.v2.c3p0.ComboPooledDataSource\"
        destroy-method=\"close\">
        <property name=\"driverClass\">
            <value>${jdbc.driver.className}</value>
        </property>
        <property name=\"jdbcUrl\">
            <value>${jdbc.url}</value>
        </property>
        <property name=\"user\">
            <value>${jdbc.username}</value>
        </property>
        <property name=\"password\">
            <value>${jdbc.password}</value>
        </property>

    </bean>

    <bean id=\"sessionFactory\"
        class=\"org.springframework.orm.hibernate4.LocalSessionFactoryBean\">
        <property name=\"dataSource\">
            <ref bean=\"dataSource\"/>
        </property>
        <property name=\"packagesToScan\" value=\"com.hp.hpl.crowdcloud\" />
        <property name=\"hibernateProperties\">
            <props>
                <prop key=\"hibernate.dialect\">${jdbc.hibernate.dialect}</prop>
                <prop key=\"hibernate.hbm2ddl.auto\">create</prop>
                <!-- uncomment this for first time run -->
                <prop key=\"hibernate.hbm2ddl.auto\">create</prop>
                <prop key=\"hibernate.show_sql\">true</prop>
            </props>
        </property>
    </bean>
    <bean id=\"transactionManager\"
        class=\"org.springframework.orm.hibernate4.HibernateTransactionManager\">
        <property name=\"sessionFactory\">
            <ref bean=\"sessionFactory\" />
        </property>
    </bean>
    <tx:annotation-driven />

</beans>

My Maven Configuration

    <maven.test.failure.ignore>true</maven.test.failure.ignore>
    <org.springframework.version>3.1.0.RELEASE</org.springframework.version>
    <hibernate.version>4.1.1.Final</hibernate.version>
    <sl4j.version>1.5.6</sl4j.version>

Kindly help me out. I am not sure where I making the mistake.


回答1:


It is due to Id column in both classes. Remove the Id from HumanMicroTask.




回答2:


to fix this Remove @Id from Subclass

in MicroTask keep

   @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    @Column(name = "MICROTASKID")
    private String microTaskId;

in Subclass HumanMicroTask remove

   @Id
    @Column(name = "HMTID")
    private String humanMicroTaskid;



回答3:


I had the same problem some time ago, since your parent class has a primary key: 'Id', when the subclasses are generated they automatically generate a foreign key with the exact name of their parent's primary key

Example: (Pseudocode)

Entity Definition

Parent Class

  @Entity
    @Inheritance(strategy = InheritanceType.JOINED)
    @Table(name = "abstract_person", catalog = "catalog", schema = "")
    class AbstractPerson{

        //Primary Key
        @Id
        @Column(name = "idPerson")
        int idPerson;

        @Basic
        @Column(name = "name")
        String name;

        //corresponding getters and setters
    }

Child Class:

 @Entity
    @Table(name = "concrete_person", catalog = "catalog", schema = "")
    class ConcretePerson extends AbstractPerson{

       //No id or primary key is defined here

        @Basic
        @Column(name="profession")
        String profession;

    }

Table Generation

Parent class will map to this

Table "abstract_person"
id: Int (primary key)
name: Varchar

Child class will map to this:


Table "concrete_person"
profession: Varchar
idPerson: int (Automatically generated, foreign key to parent table and primary class of this table)

//Assumptions
Mysql database;
Jpa 2 Hibernate Implementation;
NetBeans 7x Ide



来源:https://stackoverflow.com/questions/12087011/spring-3-1-hibernate-4-exception-for-inheritance-cannot-be-cast-to-org-hibernat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!