Hibernate 3.5中的JPA 2.0 @OrderColumn注释
我正在试图在Hibernate 3.5中使用@OrderColumn注解
@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代码需要确保List被正确更新,因为当冲洗实体时,Hibernate将忽略“one”一侧。
如果你仍然希望在Java中可以访问“one”一侧,那么将它与之映射
@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的那个,在这里你把这个关键字放在父类上,那么你意味着父母的class级不是所有者)
在你的子类中,你应该在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;