tutorial mvc framework español ejemplos edicion cuarta books arquitectura accion java spring hibernate spring-orm

java - mvc - Spring 3.1 Excepción de Hibernate 4 para herencia



spring java tutorial (3)

Hola, acabo de empezar a utilizar Spring, con Hibernate4 y maven. Básicamente, mi jerarquía de clases es HUmanMicroTask se extiende desde MicroTask. En el futuro, puede haber varias otras clases que se extienden desde MicroTask. Estaba intentando tener una tabla por clase concreta, que es la forma más sencilla de ponerme en marcha con spring3 e hibernar 4. Sin embargo, cuando ejecuto mi código. Sigo recibiendo la siguiente excepción

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

Aunque he visto bastantes foros, no estoy seguro de decidir dónde estoy cometiendo el error. Mi clase MicroTask se ve de la siguiente manera:

@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

Mi clase HumanMicroTask se ve de la siguiente manera:

@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

Y mi config.xml se ve de la siguiente manera:

<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>

Mi configuración Maven

<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>

Amablemente ayúdenme. No estoy seguro de dónde estoy cometiendo el error.


Se debe a la columna Id en ambas clases. Elimine el Id de HumanMicroTask.


Tuve el mismo problema hace un tiempo, ya que su clase principal tiene una clave principal: ''Id'', cuando se generan las subclases generan automáticamente una clave externa con el nombre exacto de la clave primaria de sus padres

Ejemplo: (Pseudocódigo)

Definición de la entidad

Clase de padres

@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 }

Clase de niños:

@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; }

Generación de tablas

La clase para padres asignará a esto

Tabla "abstract_person"
id: Int (clave principal)
nombre: Varchar

La clase infantil se asignará a esto:


Mesa "concrete_person"
profesión: Varchar
idPerson: int (Generado automáticamente, clave externa para la tabla principal y clase primaria de esta tabla)

// Suposiciones
Base de datos Mysql;
Implementación de Jpa 2 Hibernate;
NetBeans 7x Ide


para arreglar esto Retire @Id de la Subclase

en MicroTask mantener

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

en la Subclase HumanMicroTask eliminar

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