0

I'm trying to establish a tricky bidirectional OneToOne mapping in hibernate. I got the following classes :

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Parent {
     @OneToOne
     private AnotherEntity anotherEntity;
}
@Entity
public class Child1 extends Parent{}

@Entity
public class Child2 extends Parent{}

@Entity
public class AnotherEntity {

    @OneToOne(mappedBy = "anotherEntity")
    private Child1 child1;
    @OneToOne(mappedBy = "anotherEntity")
    private Child2 child2;
}

The problem here is when I'm launching the application : I got the following message :

org.hibernate.MappingException: property [anotherEntity] not found on entity [Child1]
    at org.hibernate.mapping.PersistentClass.getRecursiveProperty(PersistentClass.java:429)
    at org.hibernate.mapping.PersistentClass.getReferencedProperty(PersistentClass.java:369)
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1614)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1362)
    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:189)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:350)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:335)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
    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.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:631)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:588)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:645)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:508)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:449)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:133)
    at javax.servlet.GenericServlet.init(GenericServlet.java:160)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1266)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1185)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1080)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5015)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5302)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:895)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:871)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:615)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:962)
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:536)
    at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1471)
    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:597)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:836)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:761)
    at org.apache.catalina.manager.ManagerServlet.check(ManagerServlet.java:1436)
    at org.apache.catalina.manager.ManagerServlet.deploy(ManagerServlet.java:673)
    at org.apache.catalina.manager.ManagerServlet.doPut(ManagerServlet.java:431)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:644)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:581)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

One obvious solution would be to move the anotherEntity field to Child1 and Child2, but it would mean lose the link from Parent to AnotherEntity.

Any help welcome.

Teocali
  • 2,725
  • 2
  • 23
  • 39
  • Can we see the full stacktrace? I am having trouble reproducing the error. – jeff Jul 05 '12 at 17:24
  • Full exception stacktrace added. Additionnaly I'm using Spring for configuring hibernate, and it's a webapplication in a tomcat server, but i'm don't think it's relevant – Teocali Jul 06 '12 at 08:28
  • I found the problem could come from the inheritance. When I'm removing the line `@Inheritance(strategy = InheritanceType.JOINED)` and switch to a single table inheritance strategy (the default one), I have no more problem. – Teocali Jul 06 '12 at 08:31
  • I was not very clear in my last comment, but changing the strategy is not a possible solution, so I'm still stuck – Teocali Jul 07 '12 at 13:06

1 Answers1

1

The short answer is that you can't (with Hibernate).

First, it isn't entirely clear what you are trying to accomplish with the example given. You have specified that you want AnotherEntity to have two properties of type Child1. I am guessing that you actually want one of each, Child1 and Child2. Additionally, you are using the same mappedBy = "anotherEntity" on both properties, do you really mean you want two references on Parent to anotherEntity? In either case this helps illustrate the problem with this type of situation:

You have specified InheritanceType.JOINED, which means that the foreign key for Parent -> AnotherEntity lives on whatever table the Parent class is mapped to. Hibernate cannot distinguish between your two subtypes in this case, it would have to depend solely on the type specified in your Java class -- this could definitely lead to problems.

Apparently, other JPA providers may support this behavior (but you can see why Hibernate chose not to, and why you would need to be careful with it). For reference see this similar SO question and various discussions on Hibernate forums/JIRA:

Community
  • 1
  • 1
David
  • 1,481
  • 11
  • 19