unidirectional many to one relationship with inheritance

萝らか妹 提交于 2019-12-24 15:38:33

问题


I am trying to map a many to one relationship between class ED and class TEL in hibernate, but I am getting the following error when I try to Run As.. Run on server in eclipse:

Caused by: org.hibernate.MappingException: Could not determine type for:   
my.package.name.TEL, at table: ed, for columns: 
[org.hibernate.mapping.Column(reference)]

How can I resolve this error? The ED class only has one TEL property, but the TEL class is used as properties in so many other classes that it does not make sense to make this a bi-directional relationship. I will never need to look up all the ED objects associated with a given TEL. Most TEL instances will not have relationships with ED instances, but all ED instances will have one TEL property. Am I correctly classifying the relationship? And how to I change the code below to resolve this error? Note that inheritance is complicating things.

Here is TEL.java:

@Entity(name = "tel")
@Table(name = "tel")
public class TEL extends ANY {

    private String value;

    @Column(name = "value")
    public String getValue(){return value;}
    public void setValue(String val){value = val;}
}

Here is ED.java:

@Entity(name = "ed")
@Table(name = "ed")
public class ED extends ANY{

    private byte[] data;
    private String mediaType;
    private String language;
    private TEL reference;

    @Column(name = "data")
    public byte[] getData(){return data;}
    public void setData(byte[] d){data = d;}

    @Column(name = "mediaType")
    public String getMediaType(){return mediaType;}
    public void setMediaType(String mt){mediaType = mt;}

    @Column(name = "language")
    public String getLanguage(){return language;}
    public void setLanguage(String lng){language = lng;}

    @ManyToOne
    @JoinColumn(name = "hppid")
    public TEL getReference(){return reference;}
    public void setReference(TEL ref){reference = ref;}

}

Here is ANY.java:

@Entity(name = "rim_any")
@Table(name = "rim_any")
public class ANY extends BaseEntity{

    private CS nullFlavor;

    public CS getNullFlavor(){return nullFlavor;}
    public void setNullFlavor(CS nf){nullFlavor = nf;}

}

Here is BaseEntity.java:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorFormula("(CASE WHEN dtype IS NULL THEN 'BaseEntity' ELSE dtype END)")
@org.hibernate.annotations.DiscriminatorOptions(force=true)
public abstract class BaseEntity {

    @Transient
    private String dtype = this.getClass().getSimpleName();

    @Id 
    @GeneratedValue(
        strategy=GenerationType.TABLE, 
        generator="TBL_GEN")
    @TableGenerator(
        name="TBL_GEN",
        table="GENERATOR_TABLE",
        pkColumnName = "mykey",
        valueColumnName = "hi",
        pkColumnValue="hppid",
        allocationSize=20
    )
    protected Long hppid;

public void setHppid(Long id) {this.hppid = id;}
public Long getHppid() {return hppid;}

public void setDtype(String dt){dtype=dt;}
public String getDtype(){return dtype;}

public boolean isNew() {return (this.id == null);}

}

Here is the complete stack trace thrown when I try to Run As...Run on server from within eclipse:

ERROR ContextLoader - Context initialization failed  
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0' defined in class path resource [spring/business-config.xml]: Initialization of bean failed; nested exception is  
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [spring/business-config.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: myapp] Unable to build EntityManagerFactory
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:741) ~[spring-context-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464) ~[spring-context-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389) ~[spring-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294) ~[spring-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112) [spring-web-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4772) [catalina.jar:8.0.15]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196) [catalina.jar:8.0.15]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:8.0.15]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409) [catalina.jar:8.0.15]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399) [catalina.jar:8.0.15]
    at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_71]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_71]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_71]
    at java.lang.Thread.run(Thread.java:745) [na:1.7.0_71]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [spring/business-config.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: myapp] Unable to build EntityManagerFactory
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1512) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:438) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:277) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.<init>(PersistenceExceptionTranslationInterceptor.java:79) ~[spring-tx-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisor.<init>(PersistenceExceptionTranslationAdvisor.java:71) ~[spring-tx-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor.setBeanFactory(PersistenceExceptionTranslationPostProcessor.java:85) ~[spring-tx-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1532) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1500) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    ... 19 common frames omitted
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: myapp] Unable to build EntityManagerFactory
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:923) ~[hibernate-entitymanager-4.2.1.Final.jar:4.2.1.Final]
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:898) ~[hibernate-entitymanager-4.2.1.Final.jar:4.2.1.Final]
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:76) ~[hibernate-entitymanager-4.2.1.Final.jar:4.2.1.Final]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:288) ~[spring-orm-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310) ~[spring-orm-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1571) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1509) ~[spring-beans-3.2.5.RELEASE.jar:3.2.5.RELEASE]
    ... 34 common frames omitted
Caused by: org.hibernate.MappingException: Could not determine type for: my.package.name.TEL, at table: ed, for columns: [org.hibernate.mapping.Column(reference)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:314) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:292) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
    at org.hibernate.mapping.Property.isValid(Property.java:239) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:469) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
    at org.hibernate.mapping.UnionSubclass.validate(UnionSubclass.java:61) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1296) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1752) ~[hibernate-core-4.2.1.Final.jar:4.2.1.Final]
    at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:96) ~[hibernate-entitymanager-4.2.1.Final.jar:4.2.1.Final]
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:913) ~[hibernate-entitymanager-4.2.1.Final.jar:4.2.1.Final]
    ... 40 common frames omitted
Apr 14, 2015 6:12:45 PM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener  
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0' defined in class path resource [spring/business-config.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [spring/business-config.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: myapp] Unable to build EntityManagerFactory
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
    at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:741)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4772)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [spring/business-config.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: myapp] Unable to build EntityManagerFactory
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1512)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:438)
    at org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:277)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:139)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.<init>(PersistenceExceptionTranslationInterceptor.java:79)
    at org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisor.<init>(PersistenceExceptionTranslationAdvisor.java:71)
    at org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor.setBeanFactory(PersistenceExceptionTranslationPostProcessor.java:85)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1532)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1500)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
    ... 19 more
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: myapp] Unable to build EntityManagerFactory
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:923)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:898)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:76)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:288)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1571)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1509)
    ... 34 more
Caused by: org.hibernate.MappingException: Could not determine type for: my.package.name.TEL, at table: ed, for columns: [org.hibernate.mapping.Column(reference)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:314)
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:292)
    at org.hibernate.mapping.Property.isValid(Property.java:239)
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:469)
    at org.hibernate.mapping.UnionSubclass.validate(UnionSubclass.java:61)
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1296)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1752)
    at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:96)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:913)
    ... 40 more

Apr 14, 2015 6:12:45 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Error listenerStart
Apr 14, 2015 6:12:45 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [/myapp] startup failed due to previous errors
Apr 14, 2015 6:12:45 PM org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext
Apr 14, 2015 6:12:45 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
Apr 14, 2015 6:12:45 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-nio-8009"]
Apr 14, 2015 6:12:45 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 12061 ms

EDIT:


I tried @VladMihalCea's suggestion of:

@ManyToOne
@MapsId("hppid")
public TEL getReference(){return reference;}

in ED.java, but got the same error. I then tried his other suggestion of:

@ManyToOne
@JoinColumn(name = "ref_hppid")
public TEL getReference(){return reference;}

in ED.Java but did not make any changes to TEL.java, or to any other file. This also gives the same stack trace.

Do I need to make other changes to TEL.java? What else can I try?


回答1:


The Ed class inherits the hppid column from BaseEntity and then you duplicate it with the many-to-one association:

@ManyToOne
@JoinColumn(name = "hppid")
public TEL getReference(){return reference;}
public void setReference(TEL ref){reference = ref;}
  1. If the FK is complementary to the PK, you can simply rename it to ref_hppid

    @JoinColumn(name = "ref_hppid")
    
  2. If you want the PK and the FK to share the same column, you need to use @MapsId:

    @ManyToOne
    @MapsId("hppid")
    public TEL getReference(){return reference;}
    


来源:https://stackoverflow.com/questions/29640195/unidirectional-many-to-one-relationship-with-inheritance

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