Salut, je viens de commencer à utiliser Spring, avec Hibernate4 et maven. Fondamentalement, ma hiérarchie de classe est HUmanMicroTask s'étend de MicroTask. À l'avenir, il peut y avoir plusieurs autres classes s'étendant de MicroTask. J'essayais d'avoir une table par classe concrète, ce qui est le moyen le plus simple de démarrer avec Spring3 et d'hiberner 4. Cependant, lorsque j'exécute mon code. Je reçois toujours l'exception suivante
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
Bien que j'aie vu pas mal de forums, je ne suis pas convaincu de décider où je fais l'erreur. Ma classe MicroTask se présente comme suit:
@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
Ma classe HumanMicroTask se présente comme suit:
@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
Et mon config.xml ressemble à ceci:
<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>
Ma configuration 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>
Veuillez m'aider. Je ne sais pas où je fais l'erreur.
Cela est dû à la colonne Id dans les deux classes. Supprimez l'ID de HumanMicroTask.
résoudre ce problème Supprimer @Id de la sous-classe
dans MicroTask garder
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name = "MICROTASKID")
private String microTaskId;
dans la sous-classe HumanMicroTask supprimer
@Id
@Column(name = "HMTID")
private String humanMicroTaskid;
J'ai eu le même problème il y a quelque temps, car votre classe parent a une clé primaire: 'Id', lorsque les sous-classes sont générées, elles génèrent automatiquement une clé étrangère avec le nom exact de la clé primaire de leur parent
Exemple: (pseudocode)
Classe parent
@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
}
Classe enfant:
@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;
}
La classe parent mappera à ceci
Tableau "personne_abstraite"
id: Int (clé primaire)
nom: Varchar
La classe enfant correspondra à ceci:
Tableau "concret_personne"
profession: Varchar
idPerson: int (Généré automatiquement, clé étrangère vers la table parent et la classe primaire de cette table)
//Hypothèses
Base de données Mysql;
Jpa 2 Hibernate Implementation;
NetBeans 7x Ide