使用 Eclipse Link 2.7.4 保持双向一对多关联失败

Persisting a bi-directional One-To-Many Association fails with Eclipse Link 2.7.4

我试图保持一个简单的双向一对多关系,但在 eclipse link 2.7.4 中它失败了。下面是示例代码..

部门实体(上级)

@Entity(name = "Department")
@Table(name = "department")
@XmlAccessorType(XmlAccessType.NONE)
@Cacheable(false)
@XmlRootElement(name = "Department")
public class Department {

    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    @XmlElement(name = "id")
    private long id;


    @OneToMany(targetEntity = Employee.class, cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    @JoinColumn(name = "dept_id")
    @XmlElement(name = "employees", type = Employee.class)
    private List<Employee> employees;

    @Version
    @XmlElement(name = "version")
    private long version;

    public long getVersion() {
        return this.version;
    }

    public long getId() {
        return this.id;
    }

    public void setId(final long id) {
        this.id = id;
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }

}

雇员实体(子)

@Entity(name = "Employee")
@Table(name = "employee")
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "Employee")
public class Employee {

    public Employee() {
        super();
    }

    /**
     * The id.
     */
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    @XmlElement(name = "id")
    private long id;

    @ManyToOne(optional = false, targetEntity = Department.class, fetch = FetchType.LAZY)
    @JoinColumn(name = "dept_id", referencedColumnName = "id", nullable = false)
    private Department department;

    @Version
    @XmlElement(name = "version")
    private long version;

    public long getVersion() {
        return this.version;
    }


    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

}

测试class

public class Test {
    private static final String PERSISTENCE_UNIT_NAME = "pun";
    private static EntityManagerFactory factory;

    public static void main(String[] args) {
        factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
        EntityManager em = factory.createEntityManager();

        em.getTransaction().begin();
        Department department = new Department();
        List<Employee> dists = new ArrayList<>();

        Employee emp1 = new Employee();
        emp1.setDepartment(department);
        dists.add(emp1);

        Employee emp2 = new Employee();
        emp2.setDepartment(department);
        dists.add(emp2);

        department.setEmployees(dists);
        em.persist(department);
        em.getTransaction().commit();

        em.close();
    }
}

persistence.xml(使用 Derby 嵌入式数据库)

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="pun" transaction-type="RESOURCE_LOCAL">
        <!--  <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> -->
        <class>demo.eclipselink.error.Department</class>
        <class>demo.eclipselink.error.Employee</class>
         <properties>
          <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
          <property name="javax.persistence.jdbc.url"
            value="jdbc:derby:/databases/simpleDb;create=true" />
          <property name="javax.persistence.jdbc.user" value="test" />
          <property name="javax.persistence.jdbc.password" value="test" />

          <!-- EclipseLink should create the database schema automatically -->
          <property name="eclipselink.ddl-generation" value="create-tables" />
          <property name="eclipselink.ddl-generation.output-mode" value="database" />

          <property name="eclipselink.logging.level.sql" value="FINE"/>
        <property name="eclipselink.logging.parameters" value="true"/>
         </properties>

    </persistence-unit>
</persistence>

一旦我 运行 使用 Eclipse Link 2.7.4 的代码,它就会给我以下异常堆栈跟踪。

Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.4.v20190115-ad5b7c6b2a): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: Column name 'DEPT_ID' appears more than once times in the column list of an INSERT statement.
Error Code: 20000
Call: INSERT INTO employee (dept_id, id, VERSION, dept_id) VALUES (?, ?, ?, ?)
        bind => [1, 0, 1, 1]

我无法使用 v 2.7.3 重现此问题,并且仅在 2.7.4 中失败。我们正在使用 eclipse link 和 Payara 5.191,这个问题也存在。

如果有解决方法,请告诉我们。

谢谢

The source object must use the mappedBy attribute to define the mapping.

https://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Example_of_a_OneToMany_relationship_and_inverse_ManyToOne_annotations