使用Spring数据将下面提供的实体存储到数据库时遇到问题。在这两者之间使用OneToOne关系。仅当parentObject显式设置为childObject时,它才有效。这不是一个很好的解决方案,因为我希望子对象根本没有父对象。有可能吗? 相关的问题已发布here
@Entity
@Table(name = "parent_object")
public class ParentObject {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Long id;
@Column(name = "age")
private Long age;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "parentObject")
private ChildObject childObject;
public ParentObject() {
}
public ParentObject(Long age, ChildObject childObject) {
this.age = age;
this.childObject = childObject;
}
public Long getId() {
return id;
}
public Long getAge() {
return age;
}
public ChildObject getChildObject() {
return childObject;
}
public void setChildObject(ChildObject childObject) {
this.childObject = childObject;
}
}
@Entity
@Table(name = "child_object")
public class ChildObject {
@Id
@Column(name = "child_id", unique = true, nullable = false)
private Long id;
@MapsId
@OneToOne
@JoinColumn(name = "child_id")
private ParentObject parentObject;
@Column(name = "name")
private String name;
public ChildObject() {
}
public ChildObject(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public ParentObject getParentObject() {
return parentObject;
}
public String getName() {
return name;
}
public void setParentObject(ParentObject parentObject) {
this.parentObject = parentObject;
}
}
但是,我真的不喜欢将parentObject设置为ChildObject:
ChildObject childObject = new ChildObject("name");
ParentObject parentObject = new ParentObject(12L, childObject);
childObject.setParentObject(parentObject);
这是获得共享ID的唯一方法吗?如果未明确设置parentObject,则抛出以下错误:
Caused by: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [test.ChildObject.parentObject]
at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:83) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:101) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final]
答案 0 :(得分:1)
由于您具有双向关系(两侧都有OneToOne注释),您需要在另一侧保持关系每一侧的引用,如果您不喜欢,则可以通过以下方式将关系转换为单向关系:从一侧删除引用和映射。
答案 1 :(得分:1)
您可以轻松封装操作,以便不需要有问题的调用:实际上,您应该始终这样做,以便您的内存模型始终处于一致状态:
public class ParentObject{
public ParentObject(Long age, ChildObject childObject) {
this.age = age;
this.childObject = childObject;
childObject.setParentObject(this);
}
public void setChildObject(ChildObject childObject) {
this.childObject = childObject;
childObject.setParentObject(this);
}
}
现在,您的Domain Model API的客户端不需要了解有关后向引用表单Child to Parent的任何信息。
ChildObject childObject = new ChildObject("name");
ParentObject parentObject = new ParentObject(12L, childObject); //all relationships now set correctly