Java JPA持久性继承

Java JPA持久性继承,java,jpa,eclipselink,Java,Jpa,Eclipselink,我有一个问题,我面临了很长时间,我没有得到答案 我想用JPA保存一个继承表,但收到了一条错误消息。我用eclipselink 我的单元测试失败了 -- Table: PERSON CREATE TABLE PERSON ( ID SERIAL NOT NULL PRIMARY KEY DEFAULT nextval ('Person_Sequence'), FIRST_NAME VARCHAR NOT NULL, LAST_NAME VARCHAR

我有一个问题,我面临了很长时间,我没有得到答案

我想用JPA保存一个继承表,但收到了一条错误消息。我用eclipselink

我的单元测试失败了

    -- Table: PERSON

CREATE TABLE PERSON (
    ID SERIAL  NOT NULL PRIMARY KEY
    DEFAULT nextval ('Person_Sequence'),
    FIRST_NAME VARCHAR  NOT NULL,
    LAST_NAME VARCHAR  NOT NULL,
    DTYPE VARCHAR
);

-- Table: BUYER

CREATE TABLE BUYER (
    ID INTEGER  NOT NULL PRIMARY KEY
);
我有一个班级和餐桌的人,还有一个来自这个班级的人的次级买家

人员类别:

   import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public   class Person {

    @Id
    private int ID;
    @Column(name="FIRST_NAME")
    private String firstName;
    @Column(name="LAST_NAME")
    private String lastName;

    protected Person() {
    }

    public Person(int ID, String firstName, String lastName) {
        this.ID = ID;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public int getId() {
        return ID;
    }

    public void setId(int id) {
        this.ID = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "Person [getId()=" + getId() + ", getFirstName()=" + getFirstName() + ", getLastName()=" + getLastName()
                + "]";
    }

}
买方类别:

import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.OneToMany;

@Entity
public class Buyer extends Person {

    protected Buyer() {
    };

    public Buyer(int id, String firstName, String lastName) {
        super(id, firstName, lastName);
    }

}
到目前为止没有错误。但在这里您可以看到我的Unittest和我得到的错误消息:

import static org.junit.Assert.*;


import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class BuyerTest {

    final private int id = 33;
    final private String firstName = "Bart";
    final private String lastName = "Simpson";

    static EntityManagerFactory factory;
    static EntityManager manager;
    static EntityTransaction transaction;

    @BeforeClass
    public static void setup() {
        factory = Persistence.createEntityManagerFactory("testEclipseLink");
        assertNotNull(factory);
        manager = factory.createEntityManager();
        assertNotNull(manager);
        transaction = manager.getTransaction();
    }

    @AfterClass
    public static void teardown() {
        if (manager == null)
            return;
        manager.close();
        factory.close();
    }

    @Test
    public void create() {
        transaction.begin();
        System.out.println("first " + firstName + "last " + lastName);
        Buyer buyer = new Buyer(id, firstName, lastName);
        assertNotNull(buyer);
        manager.persist(buyer);
        transaction.commit();
    }

    @Test
    public void modify() {
        Buyer buyer = manager.find(Buyer.class, id);
        assertNotNull(buyer);
        transaction.begin();
        buyer.setFirstName("Homer");
        transaction.commit();
        teardown();
        setup();
        buyer = manager.find(Buyer.class, id);
        assertEquals("Homer", buyer.getFirstName());
    }

    @Test
    public void remove() {
        Buyer buyer = manager.find(Buyer.class, id);
        assertNotNull(buyer);
        transaction.begin();
        manager.remove(buyer);
        transaction.commit();
        buyer = manager.find(Buyer.class, id);
        assertNull(buyer);
    }




}
因此,如果我运行测试,我会出现以下错误:

[EL Warning]: 2016-10-16 19:53:54.691--UnitOfWork(2036292945)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.4.v20160829-44060b6): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: FEHLER: NULL-Wert in Spalte »first_name« verletzt Not-Null-Constraint
  Detail: Fehlgeschlagene Zeile enthält (33, null, null).
Error Code: 0
Call: INSERT INTO BUYER (ID) VALUES (?)
    bind => [1 parameter bound]
它告诉我Firstname上有一个null约束错误。但是如果我在控制台上打印名字,它就被设置了

我已经尝试过了,如果我删除了继承并使用Just我的Buyer类,它就可以正常工作了! 因此,我无法找出买家和个人类别之间的问题所在。
另外,如果这是一个Src或表定义问题,那么我能看到的第一件事是买方是个人,因此您需要在您的模式中反映这一点,添加一个外键

CREATE TABLE BUYER (
ID INTEGER  NOT NULL PRIMARY KEY,
personId bigint unsigned NOT NULL,
constraint fk_personId foreign key (personId) references PERSON (id)
))

在子类中,还需要注释

@PrimaryKeyJoinColumn(name="personId")

一个好主意是使表中的所有ID自动递增,我能看到的第一件事是,买家是个人,所以您需要在模式中添加外键来反映这一点

CREATE TABLE BUYER (
ID INTEGER  NOT NULL PRIMARY KEY,
personId bigint unsigned NOT NULL,
constraint fk_personId foreign key (personId) references PERSON (id)
))

在子类中,还需要注释

@PrimaryKeyJoinColumn(name="personId")

一个好主意是使表的所有ID自动递增

3件事:1
BUYER.ID
列应该是引用
PERSON.ID
2的FK。在
create
测试中,为什么要设置实体的id?它应该由您的DB 3设置。您的测试只有在按顺序运行时才会成功
create
->
modify
->
remove
,这既不能保证也不是一个好主意错误显示EclipseLink正在发出预期的“插入买方(ID)值(?)语句-这将只传入ID。它应该在PERSON表中发出单独的语句,以插入ID、FIRST_NAME和LAST_NAME字段。打开SQL日志以查看发生了什么,但我怀疑您的数据库没有按照您提到的方式进行设置。不知何故,您的买家表需要FIRST_NAME和LAST_NAME字段,这些字段在您在JPA中配置的表模型中不存在。也许你想使用InheritanceType.TABLE_PER_类而不是Join类?3件事:1
BUYER.ID
列应该是引用
PERSON.ID
2的FK。在
create
测试中,为什么要设置实体的id?它应该由您的DB 3设置。您的测试只有在按顺序运行时才会成功
create
->
modify
->
remove
,这既不能保证也不是一个好主意错误显示EclipseLink正在发出预期的“插入买方(ID)值(?)语句-这将只传入ID。它应该在PERSON表中发出单独的语句,以插入ID、FIRST_NAME和LAST_NAME字段。打开SQL日志以查看发生了什么,但我怀疑您的数据库没有按照您提到的方式进行设置。不知何故,您的买家表需要FIRST_NAME和LAST_NAME字段,这些字段在您在JPA中配置的表模型中不存在。也许您想使用InheritanceType.TABLE_PER_类而不是JOINED?
买家的PK应该是共享密钥(即也是FK),不需要额外的FK。当它与
买家
的PK同名时,不需要注释,PK应该是共享密钥(即也是FK),不需要额外的FK。当它与
人的名字相同时,就不需要注释了