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;
我在 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;