带有OneToOne主键/外键类型关系的JPA Hibernate空指针异常

时间:2016-02-10 12:05:02

标签: java jpa foreign-key-relationship one-to-one metamodel

我正在尝试构建一个小原型,我遇到了很多麻烦。

问题涉及两个实体。但要理解它,我需要描述其他一些。

就数据库结构而言,可以描述如下:

Person
----------------
id   Integer PK
surname VARCHAR 
givenNames VARCHAR

TypedIdentifier
----------------
idCode  VARCHAR PK FK (IdType.code)
idVal   VARCHAR PK
person  Integer FK  (Person.id)

IdType
------
code   VARCHAR PK

IdDescription
----------
code   VARCHAR PK FK   (IdType.code)
category VARCHAR 
name    VARCHAR

我的问题出现在表IdDescription和IdType 之间的 关系中。

基本上,IdType表应该包含一个列,即主键(唯一)和辅助表(IdDescription),它描述了id-type,应该有一个该列的外键。

指导我设计数据库的两个要点:

  1. IdType.code在它自己的单独表中,因为我想将Id与IdDescription隔离(从Java结构的角度来看)
  2. 因为两个表TypedIdentifier和IdDescription都需要引用IdType,所以我只能在THOSE表中对IdType进行引用/关系注释(在IdType本身中没有)。
  3. 我的Java代码如下所示:

    @MappedSuperclass
    public class Person implements Serializable
    {
        /**
         * internal unique identifier
         */
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        public Integer id;
    
        /**
         * 
         * Assigned patient identifiers
         */
        @OneToMany(targetEntity=TypedIdentifier.class, mappedBy="ownerPerson", fetch=FetchType.EAGER)
        public List<TypedIdentifier> patientIdentifiers;
    
        /**
         * natural identifiers
         */
        public String surname;
    
        public String givenNames;
    }
    

    TypedIdentifier

    @Table(uniqueConstraints = @UniqueConstraint(columnNames={"idType", "idValue"}))
    @Entity @IdClass(TypedIdentifier.class)
    public class TypedIdentifier implements Serializable
    {
        /**
         * internal unique identifier
         */
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        public Integer id;
    
        @Id
        @ManyToOne(fetch=FetchType.LAZY)    
        public IdType idType;   // should be a foreign key
    
        @Id
        public String idValue;
    
        @ManyToOne(fetch=FetchType.LAZY)
        @JoinColumn
        public Person ownerPerson;
    }
    

    IdType

    @Entity
    public class IdType implements Serializable
    {
        @Id
        public String code;
    }
    

    IdTypeDescription

    @Entity
    public class IdTypeDescription implements Serializable
    {
        @MapsId
        @JoinColumn(name = "code")
        @OneToOne(cascade = CascadeType.ALL, mappedBy="code")  
        public IdType itype;
    
        public IdCategory category;
    
        public String name;
    }
    

    如果我需要在SQL中编写它,我就没有问题。但是使用JPA / Hibernate,一件简单的事情就变成了一场噩梦。我从一个错误反弹到另一个错误然后又回来了。

    我的问题似乎来自我对IdTypeDescription的itype成员的注释。我尝试了各种方法(基于示例代码和API文档)。

    这些注释组合导致我的元模型生成器不为我的静态类生成属性 IdTypeDescription _

    @MapsId
    @JoinColumn(name = "code")
    @OneToOne(cascade = CascadeType.ALL, mappedBy="code")   
    public IdType itype;
    

    这些注释组合在hibernate中导致空指针异常,因为它试图创建表:

    @Id
    @OneToOne(cascade = CascadeType.ALL, mappedBy="code")
    public IdType itype;    
    

    @Id
    @OneToOne(cascade = CascadeType.ALL, mappedBy="code")
    @PrimaryKeyJoinColumn
    public IdType itype;    
    

    错误:

    play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[ProvisionException: Unable to provision, see the following errors:
    
    1) Error injecting constructor, javax.persistence.PersistenceException: Unable to build entity manager factory
      at play.db.jpa.DefaultJPAApi$JPAApiProvider.<init>(DefaultJPAApi.java:35)
      at play.db.jpa.DefaultJPAApi$JPAApiProvider.class(DefaultJPAApi.java:30)
      while locating play.db.jpa.DefaultJPAApi$JPAApiProvider
      while locating play.db.jpa.JPAApi
    
    1 error]]
        at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:265) ~[play_2.11-2.4.4.jar:2.4.4]
        at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:191) ~[play_2.11-2.4.4.jar:2.4.4]
    
        at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [scala-library-2.11.6.jar:na]
        at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [scala-library-2.11.6.jar:na]
    Caused by: com.google.inject.ProvisionException: Unable to provision, see the following errors:
    
    1) Error injecting constructor, javax.persistence.PersistenceException: Unable to build entity manager factory
      at play.db.jpa.DefaultJPAApi$JPAApiProvider.<init>(DefaultJPAApi.java:35)
      at play.db.jpa.DefaultJPAApi$JPAApiProvider.class(DefaultJPAApi.java:30)
      while locating play.db.jpa.DefaultJPAApi$JPAApiProvider
      while locating play.db.jpa.JPAApi
    
    1 error
        at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1025) ~[guice-4.0.jar:na]
        at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051) ~[guice-4.0.jar:na]
    
    
        at com.google.inject.internal.InjectorImpl$2$1.call(InjectorImpl.java:1016) ~[guice-4.0.jar:na]
        at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092) ~[guice-4.0.jar:na]
        at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1012) ~[guice-4.0.jar:na]
        ... 38 common frames omitted
    Caused by: java.lang.NullPointerException: null
        at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processFkSecondPassesInOrder(InFlightMetadataCollectorImpl.java:1708) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
        at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1617) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
        at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:770) ~[hibernate-entitymanager-5.0.5.Final.jar:5.0.5.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:797) ~[hibernate-entitymanager-5.0.5.Final.jar:5.0.5.Final]
        at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58) ~[hibernate-entitymanager-5.0.5.Final.jar:5.0.5.Final]
        ... 57 common frames omitted
    

0 个答案:

没有答案