Hibernate 3.5中的@OrderColumn注释

Pio*_*zda 25 hibernate jpa one-to-many jpa-2.0

我正在尝试使用@OrderColumnHibernate 3.5 的注释

@OneToMany(mappedBy = "parent",fetch=FetchType.EAGER, cascade=CascadeType.ALL)
@OrderColumn(name = "pos")
private List<Children> childrenCollection;
Run Code Online (Sandbox Code Playgroud)

检索数据时,一切正常.但我不能让它重新排序列表中的元素并将新订单保存到数据库.

Pet*_*raf 29

Hibernate不支持@OneToMany(mappedBy ="...")和@OrderColumn的组合.当使用此无效组合时,此JIRA问题会跟踪发出更明显错误消息的请求:http://opensource.atlassian.com/projects/hibernate/browse/HHH-5390

我认为这不受支持主要是因为它是一种奇怪的关系模式.上面的注释表明关系的"一"侧决定了如何将关系刷新到数据库,但是通过检查List,订单/位置仅在"多"侧可用.对于"很多"方来说,拥有这种关系更有意义,因为那一方知道元素的成员资格和顺序.

Hibernate Annotations文档详细描述了这种情况:

http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#entity-hibspec-collection-extratype-in​​dexbidir

解决方法是删除"mappedBy"属性,这将导致关联使用默认连接表策略而不是目标表上的列.您可以使用@JoinTable批注指定连接表的名称.

这种变化的净效应是,关系的"多"方现在决定了这种关系是如何持续存在的.你的java代码需要确保List正确更新,因为Hibernate现在会在刷新实体时忽略"one"方面.

如果您仍希望在Java中访问"one"端,请将其映射

@ManyToOne
@JoinColumn(name="...", insertable=false, updatable=false, nullable=false)
Run Code Online (Sandbox Code Playgroud)

  • 我天真的猜测是每个提供商都支持这个,因为它是一个非常标准的映射.像往常一样,Hibernate是奇怪的.它基本上是JPA提供商下的IE6 :( (6认同)
  • 有趣的是,显式索引列的"官方"示例恰好使用了组合`@OneToMany(mappedBy ="...")`+`@ OrderColumn`(参见http://docs.jboss.org/中的示例7.8)休眠/核心/ 3.6 /参考/ EN-US/HTML/collections.html#集合索引) (5认同)
  • 在回答之后,人们一致认为必须支持这种情况.Gail Badner:"我同意应该支持@OneToMany(mappedBy ="......")." (2认同)
  • 我不知道为什么这是一个“奇怪的关系模式”。不是。问问 JPA 的人就知道了。 (2认同)

Dan*_*eón 10

做这样的事情:

@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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为在prepareIndex()中它应该改为index = parent.children.indexOf(this); if(index == -1)index = parent.children.size(); (2认同)