Skip to content


Using Spring and Hibernate With JPA And Entity Interfaces

I'm currently setting up a new Hibernate project and finally getting around to trying out JPA annotations instead of using any Hibernate configuration or mapping files-- what the hell took me so long!!??! Anyhow, among the many gotchas I came across, one was how to deal with using Interfaces with Hibernate entity beans and associations.

When you declare an association to a Hibernate Entity with an Interface without using the correct annotation syntax to point Hibernate at the implementing class, you will likely see exceptions like this while running JUnit 4 tests in Eclipse:

CODE:
  1. java.lang.IllegalStateException: Failed to load ApplicationContext
  2.     at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:201)
  3.     at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
  4.     at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
  5.     at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:255)
  6.     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:111)
  7.     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:148)
  8.     at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
  9.     at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
  10.     at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
  11.     at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
  12.     at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
  13.     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:97)
  14.     at org.junit.internal.runners.CompositeRunner.runChildren(CompositeRunner.java:33)
  15.     at org.junit.runners.Suite.access$000(Suite.java:26)
  16.     at org.junit.runners.Suite$1.run(Suite.java:93)
  17.     at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
  18.     at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
  19.     at org.junit.runners.Suite.run(Suite.java:91)
  20.     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
  21.     at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
  22.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
  23.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
  24.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
  25.     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
  26. Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'geoSessionFactory' defined in class path resource [com/peerdigital/spring/applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com.peerdigital.geolocation.model.DefaultCountryEntityImpl.regionEntity references an unknown entity: com.peerdigital.geolocation.model.DefaultRegionEntityImpl
  27.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1338)
  28.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
  29.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
  30.     at java.security.AccessController.doPrivileged(Native Method)
  31.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
  32.     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
  33.     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
  34.     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
  35.     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
  36.     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
  37.     at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:423)
  38.     at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
  39.     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
  40.     at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:84)
  41.     at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:42)
  42.     at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:173)
  43.     at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:197)
  44.     ... 23 more
  45. Caused by: org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com.peerdigital.geolocation.model.DefaultCountryEntityImpl.regionEntity references an unknown entity: com.peerdigital.geolocation.model.DefaultRegionEntityImpl
  46.     at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:81)
  47.     at org.hibernate.cfg.AnnotationConfiguration.processEndOfQueue(AnnotationConfiguration.java:456)
  48.     at org.hibernate.cfg.AnnotationConfiguration.processFkSecondPassInOrder(AnnotationConfiguration.java:438)
  49.     at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:309)
  50.     at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1148)
  51.     at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:673)
  52.     at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211)
  53.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369)
  54.     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)
  55.     ... 39 more

Most of the solutions I saw made you create a duplicate persistence.xml that had all of the same information in it which seemed silly to me. Eventually with the help of Google I came across the answer somewhere (which I no longer have around) which was to modify the field annotation to point at the class which implements the Interface:

CODE:
  1. @ManyToOne(targetEntity = DefaultRegionEntityImpl.class)
  2. @JoinColumn(name = "region_code_fk", referencedColumnName = "region_code_pk", insertable = false, updatable = false)
  3. private RegionEntity regionEntity;

One other thing to check-- make sure your @Entity annotation is importing the JPA annotation (javax.persistence.Entity), and NOT the Hibernate annotation (org.hibernate.annotations.Entity). If you import the Hibernate @Entity annotation it will not find the entity bean.

Hopefully that's of some help to someone. Just a quick post-- back to work I go!

Posted in Frameworks, Hibernate, Java, Languages, Spring. Tagged with , , , , , .

One Response

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Dave H said

    Good Explanation. Thanks

Some HTML is OK

(required)

(required, but never shared)

or, reply to this post via trackback.