EclipseLink - Weblogic 12 - 使用双向映射插入顺序问题

EclipseLink - Weblogic 12 - Insert order issue using Bidirectional mapping

我在 Weblogic 12 上使用 EclipseLink (JPA2) 时遇到问题。 我在互联网上搜索了一个解决方案,但在花了太多时间没有找到解决方案后,我决定请求您的经验:也许你们中的一个可以帮助我。

(此映射在 WL 10.3.3 - EclipseLink (JPA1) 上完美运行)

基本用户故​​事:应用程序的任何 'power' 用户(称为 'employers')都能够对其他用户提出一些请求(更改)。您可以考虑一些'employers'(HR,经理)可以请求对其他组织的员工进行一些更改(地址更改,从一个部门转移到另一个部门(或组建一个团队到另一个团队),雇用新员工,解雇雇主等等...

我的结构如下:

任何类型的 'request' 都继承自 REQUEST(一个对象和一个 table - 持有所有请求之王的 PK)。例如:HiringRequest、EmployerModificationRequest、FiringRequest、TransferRequest(其中有 subClasses/subTypes)。

@Entity
@Converter(name = "code", converterClass = CodeConverter.class)
@Table(name = "REQUEST")
@Inheritance(strategy = JOINED)
@DiscriminatorColumn(name = "REQUEST_DISC", discriminatorType = STRING)
@SequenceGenerator(name = "REQUEST_SEQ", sequenceName = "Request_Sequence", allocationSize = 1, initialValue = 1)
public abstract class Request implements Serializable {

    private static final long serialVersionUID = 5740148848518876165L;

    @Id
    @Column(name = "REQUEST_ID", nullable = false, length = 16)
    @GeneratedValue(generator = "REQUEST_SEQ")
    private long requestId;
...

}

@Entity
@Table(name = "TRANSFER_REQUEST")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@PrimaryKeyJoinColumn(name = "REQUEST_ID")
public abstract class TransferRequest extends Request {

    private static final long serialVersionUID = 1L;

    ...
    @OneToMany(cascade = ALL, mappedBy = "transferRequest")
    private List<EmployeeInTransfer> employees;


    public List<EmployeeInTransfer> getSourceEmployers() {
        return employees;
    }

    public void setSourceEmployers(List<EmployeeInTransfer> inEmployees) {
        for (EmployeeInTransfer employee : inEmployees) {
            employee.setTransferRequest(this);
        }
        this.employees = inEmployees;
    }
    ...
}

@Entity
@DiscriminatorValue("TEAM_CHANGE")
public class TeamChangeRequest extends TransferRequest {

    private static final long serialVersionUID = 5747883857562212522L;

    ...

}

雇主调动

@Entity
@Table(name = "EMPLOYEE_IN_TRANSFER")
@SequenceGenerator(name = "EMPLOYEE_IN_TRANSFER_SEQ", sequenceName = "Employee_In_Transfer_Sequence", allocationSize = 1, initialValue = 1)
public class EmployeeInTransfer implements Serializable {

    private static final long serialVersionUID = 8987161385291888922L;

    @Id
    @Column(name = "EMPLOYEE_IN_TRANSFER_ID", nullable = false, length = 16)
    @GeneratedValue(generator = "EMPLOYEE_IN_TRANSFER_SEQ")
    private Long id;

    @ManyToOne(optional = false, fetch=LAZY)
    @JoinColumn(name = "TRANSFER_REQUEST_ID", nullable=false)
    private TransferRequest transferRequest;

    ...
}

而测试 class 是测试持久性:

@Test
    public void teamChangePersistenceTest() {

        DateTime creationOrReceptionDate = toDateTime(getDate(2010, 5, 5)).minusDays(5);

        TransferRequest transferRequest = aTeamChangeRequest()
            .withCreationDateTime(creationOrReceptionDate.toDate())
            .build();
        em.persist(transferRequest);

        em.flush();  
    }

日志显示如下:

...
[EL Fine]: sql: 2016-01-22 11:02:06.962--INSERT INTO REQUEST ...
[EL Fine]: sql: 2016-01-22 11:02:06.986--INSERT INTO CATEGORY ...
[EL Fine]: sql: 2016-01-22 11:02:06.995--INSERT INTO EMPLOYEE_IN_TRANSFER ...
[EL Fine]: sql: 2016-01-22 11:02:07.041--SELECT 1 FROM DUAL
[EL Warning]: 2016-01-22 11:02:07.05--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.2.v20130514-5956486): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.BatchUpdateException: ORA-02291: integrity constraint (MYSCHEMA.FK_EIT_TR) violated - parent key not found

所以... 如果禁用约束,则 TeamChangeRequest 的持久性发生在 EmployerInTransfer Objets 之后,一切都很好。 如果启用约束(这应该是正确的情况),由于插入语句的顺序错误,我将面临违反约束的情况。

Request 是 TransferRequest (TeamChangeRequest) 的父级,它负责(父级)与 EmployeeInTransfer(子级)的关系。

我如何调整 EclipseLink 以确保在任何 EmployeeInTransfer 语句之前插入 TeamChangerequest 对象?

你知道我该如何解决吗?

由于继承关系,Request实体是有主键的; JPA 限制实体仅引用主键,EclipseLink 相应地优化了插入。

这意味着与连接列 "TRANSFER_REQUEST_ID" 的 EmployeeInTransfer transferRequest 关系应该对 REQUEST table 有约束,而不是 "TRANSFER_REQUEST" table。

就是说,您可以在连接列中告诉 EclipseLink 它特别连接到哪个字段,而不是让它默认为 REQUEST table。指定包含 referencedColumnName 的 table 而不是让它默认:

@ManyToOne(optional = false, fetch=LAZY)
@JoinColumn(name = "TRANSFER_REQUEST_ID", referencedColumnName="TRANSFER_REQUEST.REQUEST_ID", nullable=false)
private TransferRequest transferRequest;