具有继承的单向多对一关系

unidirectional many to one relationship with inheritance

我试图在休眠中映射 class EDclass TEL 之间的多对一关系,但是当我尝试在 eclipse 中映射 Run As.. Run on server 时出现以下错误:

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

我该如何解决这个错误? ED class 只有一个 TEL 属性,但 TEL class 在许多其他 class 中用作属性,因此将其设为 bi 没有意义-方向关系。我永远不需要查找与给定 TEL 关联的所有 ED 对象。 大多数TEL实例不会与ED实例有关系,但所有ED实例都会有一个TEL 属性。我是否正确 class 确定了关系?以及如何更改下面的代码来解决此错误? 请注意,继承使事情变得复杂。

这里是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;}
}

这是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;}

}

这是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;}

}

这是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);}

}

这是我尝试从 eclipse 中 Run As...Run on server 时抛出的完整堆栈跟踪:

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

编辑:


我尝试了@VladMihalCea 的建议:

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

在ED.java,但得到了同样的错误。然后我尝试了他的另一个建议:

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

在 ED.Java 中,但没有对 TEL.java 或任何其他文件进行任何更改。这也给出了相同的堆栈跟踪。

我是否需要对 TEL.java 进行其他更改?我还能尝试什么?

Ed class 继承了 BaseEntityhppid 列,然后您使用多对一关联复制它:

@ManyToOne
@JoinColumn(name = "hppid")
public TEL getReference(){return reference;}
public void setReference(TEL ref){reference = ref;}
  1. 如果FK与PK互补,可以直接重命名为ref_hppid

    @JoinColumn(name = "ref_hppid")
    
  2. 如果要PK和FK同列,需要使用@MapsId:

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