我与 @OneToMany
和 @ManyToOne
注释有简单的父子关系。
@Entity
public class Parent {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", fetch = FetchType.LAZY)
private List<Child> children = new ArrayList<>();
}
public class Child {
@ManyToOne( fetch = FetchType.LAZY, optional = false)
@JoinColumn( name = "parent_id" )
@ForeignKey( name = "fk_child_parent" )
private Parent parent;
}
但我还想保留对 Parent
实体中当前(最后一个)子项的引用。
如何以正确的方式做到这一点?我应该在 Parent
中引入新的无向 @OneToOne
关系吗?像这样:
@OneToOne( optional = true, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn( name = "current_child_id", nullable = false )
@ForeignKey( name = "FK_parent_child" )
private Child currentChild;
最佳答案
因此,在应用程序启动时,您总是会遇到确定现有父元素和子元素的子元素插入顺序的问题。因此,您应该将此数据保留在持久层中。
向您的子类添加创建(或更新)的时间戳,您可以自己决定如何处理该字段的初始化(即使用列默认值或触发器等)。现在,您的代码中应该可以使用所需的信息,只需向您的子类添加一个“compareTo”方法(用于排序),然后向您的父类添加以下 getMostRecentChild
方法即可。
@Entity
public class Parent {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", fetch = FetchType.LAZY)
public List<Child> children = new ArrayList<>();
public Child getMostRecentChild() {
if(children == null || children.isEmpty()) {
return null;
}
return Collections.sort(children).get(0);
}
}
public class Child {
@ManyToOne( fetch = FetchType.LAZY, optional = false)
@JoinColumn( name = "parent_id" )
@ForeignKey( name = "fk_child_parent" )
public Parent parent;
@Column( name = "created_ts" )
public createdTs;
public int compareTo(Child other) {
return created_ts.compareTo(other);
}
}
如何找到 currentChild 的实现细节是无关紧要的。您还可以使用 TreeSet 或仅使用循环来查找 currentChild。
编辑:论证为什么这比 currentChild 列更好。
如果您不喜欢上面的答案,请考虑以下内容
- 添加 currentChild 字段可提供对同一对象的两个引用。因此,它没有标准化,而添加时间戳会向您的模式添加一个标准化列,您可以轻松地通过与您尝试封装在 currentChild 中的逻辑直接耦合的方式从中导出您需要的信息(以及更多信息)专栏。
- 为了确保您的 currentChild 不会与其预期值不匹配,您必须将其逻辑封装在 Hibernate 对象中(然后您可以在数据库级别覆盖该对象),或者使用数据库级别的触发器来封装它,这可以丑陋且难以追踪(而created_ts字段的默认值和“ON UPDATE”是相当常见的地方)
关于java - hibernate 。保留对最后一个 child 的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29870817/