我正在尝试将@OrderColumn
注释与 Hibernate 3.5一起使用
@OneToMany(mappedBy = "parent",fetch=FetchType.EAGER, cascade=CascadeType.ALL)
@OrderColumn(name = "pos")
private List<Children> childrenCollection;
检索数据时,一切正常。但我不能让它重新排序列表中的元素并将新订单保存到数据库中。
我正在尝试将@OrderColumn
注释与 Hibernate 3.5一起使用
@OneToMany(mappedBy = "parent",fetch=FetchType.EAGER, cascade=CascadeType.ALL)
@OrderColumn(name = "pos")
private List<Children> childrenCollection;
检索数据时,一切正常。但我不能让它重新排序列表中的元素并将新订单保存到数据库中。
Hibernate 不支持 @OneToMany(mappedBy="...") 和 @OrderColumn 的组合。此 JIRA 问题跟踪使用此无效组合时抛出更明显错误消息的请求:http: //opensource.atlassian.com/projects/hibernate/browse/HHH-5390
我认为这不被支持主要是因为它是一种奇怪的关系模式。上面的注释表明关系的“一”侧决定了该关系将如何刷新到数据库中,但是通过检查列表,订单/仓位仅在“多”侧可用。“多”方拥有关系更有意义,因为该方知道成员资格和元素的顺序。
Hibernate Annotations 文档详细描述了这种情况:
解决方法是删除“mappedBy”属性,这将导致关联使用默认的连接表策略而不是目标表上的列。您可以使用 @JoinTable 注释指定连接表的名称。
这种变化的最终结果是关系的“多”方现在决定了关系的持久性。您的 java 代码需要确保正确更新列表,因为 Hibernate 现在在刷新实体时将忽略“一”侧。
如果您仍然希望在 Java 中访问“一个”端,请将其映射为
@ManyToOne
@JoinColumn(name="...", insertable=false, updatable=false, nullable=false)
做这样的事情:
@Entity
class Parent {
@OneToMany
@OrderColumn(name = "pos")
List<Child> children;
}
@Entity
class Child {
@ManyToOne
Parent parent;
@Column(name = "pos")
Integer index;
@PrePersist
@PreUpdate
private void prepareIndex() {
if (parent != null) {
index = parent.children.indexOf(this);
}
}
}
您应该尝试在关联的所有者上指定 OrderColumn。或者在您的映射中,您将所有者放在孩子身上,所有者应该是父母(在双向关联中,所有者是没有关键字 mappedBy 的人,在这里您将此关键字放在父母的类上,然后您表示父母的班级不是所有者)
在您的子类中,您应该在 parentCollection 上有关键字 mappedBy。但不在 childrenCollection 上。
在您的父类中,您应该有注释@JoinTable,如下所示:
@OneToMany(mappedBy = "parent",fetch=FetchType.EAGER, cascade=CascadeType.ALL)
@OrderColumn(name = "pos")
@JoinTable( name = "<NAME_OF_YOUR_TABLE>", joinColumns = @JoinColumn( <JOIN_COLUMNS_...> )
private List<Children> childrenCollection;