JPA: 一对一 + 自引用 + 双向

3
我有一个名为“Instructions”的实体。有时需要跟踪它之前和之后的指令。例如,我有一个新的指令B,它是从现有的指令A继续的,指令B必须知道指令A是前一个指令,而指令A也必须知道指令B是其后续指令。并非每个指令都会有前面和后面的指令。
在JPA(EclipseLink)中如何实现此功能:[one-to-one + self referential + bidirectional]关系?
到目前为止(尚未工作),我想到了以下内容:
mysql数据库:
CREATE TABLE instructions (
instruction_id int(11) NOT NULL AUTO_INCREMENT,
instruction_title varchar(100) NOT NULL,
instruction_text varchar(999) NOT NULL,
instruction_previous_id int(11) DEFAULT NULL,
PRIMARY KEY (instruction_id),
CONSTRAINT instructions_ibfk_3 
FOREIGN KEY (instruction_previous_id) 
REFERENCES instructions (instruction_id));

实体:

@Entity
@Table(name = "instructions")
public class Instructions implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "instruction_id")
private Integer instructionId;
@Basic(optional = false)
@Column(name = "instruction_title")
private String instructionTitle;
@Basic(optional = false)
@Column(name = "instruction_text")
private String instructionText;

@JoinColumn(name="instruction_previous_id", referencedColumnName = "instruction_id", nullable = true)
@OneToOne(optional = true)
private Instructions instructionPrevious;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "instructionPrevious")
private Collection<Instructions> instructionNextCollection;
// other properties, setter & getter
}

目前创建新指令没有问题,但是读取时出现了错误。

Instructions instruction = em.find(Instructions.class, instructionId);
instruction.getInstructionNextCollection().size(); //error this line

本地异常堆栈: 异常[EclipseLink-4002] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.DatabaseException 内部异常: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 表 'atiits.instructions_instructions' 不存在 错误代码: 1146 调用: SELECT t1.instruction_id, t1.instruction_urgent, t1.instruction_uploaded_by, t1.instruction_translate, t1.instruction_title, t1.instruction_type, t1.instruction_translate_received, t1.instruction_is_cancelled, t1.instruction_translate_sent, t1.instruction_had_workorder, t1.instruction_text, t1.instruction_update_date, t1.instruction_update_by, t1.instruction_create_by, t1.instruction_translator, t1.instruction_create_date, t1.instruction_company_id, t1.instruction_previous_id, t1.instruction_status_id FROM instructions_instructions t0, instructions t1 WHERE ((t0.Instructions_instruction_id = ?) AND (t1.instruction_id = t0.instructionNextCollection_instruction_id)) bind => [874] 查询: ReadAllQuery(name="instructionNextCollection" referenceClass=Instructions sql="SELECT t1.instruction_id, t1.instruction_urgent, t1.instruction_uploaded_by, t1.instruction_translate, t1.instruction_title, t1.instruction_type, t1.instruction_translate_received, t1.instruction_is_cancelled, t1.instruction_translate_sent, t1.instruction_had_workorder, t1.instruction_text, t1.instruction_update_date, t1.instruction_update_by, t1.instruction_create_by, t1.instruction_translator, t1.instruction_create_date, t1.instruction_company_id, t1.instruction_previous_id, t1.instruction_status_id FROM instructions_instructions t0, instructions t1 WHERE ((t0.Instructions_instruction_id = ?) AND (t1.instruction_id = t0.instructionNextCollection_instruction_id))") at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333) at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:687)


可能是 https://dev59.com/HnA75IYBdhLWcg3wRWoU 的重复问题。 - perissf
1个回答

4
在你的示例中有些混淆,不清楚每个指令是可以跟随一个还是多个Instruction。
如果只跟随一个,则不要使用instructionNext集合。
如果跟随多个,则JPA: How to have one-to-many relation of the same Entity type中的示例代码应该会有所帮助。你需要在前面的指令上使用@ManyToOne,并在后面使用@OneToMany,而不是@OneToOne

谢谢你的回复 :D,每个指令只能跟随一个指令(一对一),那么我应该用什么来声明instructionNext? - blukit
1
只需将“Collection<Instructions>”替换为“Instructions” - 这样行吗? - Andrew Spencer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接