JPA: один к одному + самоссылка + двунаправленный - PullRequest
3 голосов
/ 16 февраля 2012

У меня есть объект под названием «Инструкции». Иногда каждая инструкция должна отслеживать инструкции до и после нее. Например, у меня есть новая инструкция B, которая продолжается от существующей инструкции A, Инструкция B должна знать, что Инструкция A является предыдущей инструкцией, в то время как Инструкция A также должна знать, что Инструкция B является следующей после нее. Не каждая инструкция будет иметь до и после инструкции.

Как реализовать это в JPA (EclipseLink): [один-к-одному + самоссылочная + двунаправленная] связь?

Пока (пока не работает) я придумал это:

mysql db:

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

Local Exception Stack: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.0.1.v20100213-r6600): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'atiits.instructions_instructions' doesn't exist Error Code: 1146 Call: 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] Query: 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)

1 Ответ

3 голосов
/ 16 февраля 2012

В вашем примере есть некоторая путаница, может ли каждая инструкция следовать одной или нескольким инструкциям.

Если это одна инструкция, то не используйте коллекцию для обучения далее.

Если их много, то пример кода в JPA: Как иметь отношение «один ко многим» одного и того же типа сущности , должно помочь.Вам нужно @ManyToOne для предыдущей инструкции и @OneToMany для следующей, а не @OneToOne.

...