Мне очень трудно добиться однонаправленной однозначной связи для работы с JPA (Поставщик: Hibernate) . На мой взгляд, это не должно вызывать особых проблем, но очевидно, что JPA / Hibernate не согласен с этим; -)
Проблема в том, что мне нужно сопоставить устаревшую схему, которую я не могу изменить, и что эта схема использует общий первичный ключ между двумя объектами, которые в то же время являются внешним ключом для одного объекта.
Я создал простой TestCase:
БД выглядит следующим образом:
CREATE TABLE PARENT (PARENT_ID Number primary key, Message varchar2(50));
CREATE TABLE CHILD (CHILD_ID Number primary key, Message varchar2(50),
CONSTRAINT FK_PARENT_ID FOREIGN KEY (CHILD_ID )REFERENCES PARENT (PARENT_ID));
CREATE SEQUENCE SEQ_PK_PARENT START WITH 1 INCREMENT BY 1 ORDER;
Родитель (= владеющая сторона взаимно-однозначного соответствия) выглядит следующим образом:
@Entity
@Table(name = "PARENT")
public class Parent implements java.io.Serializable {
private Long parentId;
private String message;
private Child child;
@Id
@Column(name = "PARENT_ID", unique = true, nullable = false, precision = 22, scale = 0)
@SequenceGenerator(name="pk_sequence", sequenceName="SEQ_PK_PARENT")
@GeneratedValue(generator="pk_sequence", strategy=GenerationType.SEQUENCE)
public Long getParentId() {
return this.parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
@Column(name = "MESSAGE", length = 50)
public String getMessage() {
return this.message;
}
public void setMessage(String message) {
this.message = message;
}
@OneToOne (cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn(name="PARENT_ID", referencedColumnName="CHILD_ID")
public Child getTestOneToOneChild() {
return this.child;
}
public void setTestOneToOneChild(Child child) {
this.child = child;
}
}
Ребенок:
@Entity
@Table(name = "TEST_ONE_TO_ONE_CHILD", schema = "EXTUSER")
public class Child implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Long childId;
private String message;
public Child() {
}
public Child(String message) {
this.message = message;
}
@Id
@Column(name = "CHILD_ID")
public Long getChildId() {
return this.childId;
}
public void setChildId(Long childId) {
this.childId = childId;
}
@Column(name = "MESSAGE", length = 50)
public String getMessage() {
return this.message;
}
public void setMessage(String message) {
this.message = message;
}
}
Я полностью вижу проблему в том, что JPA не знает, как назначить идентификатор для ребенка. Однако я также пробовал использовать Hibernates «чужой». Мне эта проблема не кажется такой уж необычной, так что мне здесь не хватает? Есть ли вообще решение? Я также могу использовать расширения hibernate, если чистый JPA не дает решения.
Мои ожидания от правильного поведения были бы следующими: Если я попытаюсь сохранить родительский элемент с прикрепленным дочерним элементом:
Если я попытаюсь сохранить "автономный" дочерний элемент (например, entityManager.persist (aChild)), я бы ожидал исключения RuntimeException.
Любая помощь приветствуется!