开发者

@OrderColumn annotation in Hibernate 3.5

I'm trying to use the @OrderColumn annotation with Hibernate 3.5

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

When retrieving data, everythin开发者_运维技巧g works fine. But I can't make it reorder elements in the List and save the new order to the database.


The combination of @OneToMany(mappedBy="...") and @OrderColumn is not supported by Hibernate. This JIRA issue tracks a request to throw a more obvious error message when this invalid combination is used: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5390

I think that this isn't supported mainly because it is an odd relational pattern. The annotations above indicate that the "one" side of the relationship determines how the relationship will be flushed to the database, but the order/position is only available on the "many" side by examining the List. It makes more sense for the "many" side to own the relationship, since that side knows about both the membership and the ordering of the elements.

The Hibernate Annotations docs describe this situation in some detail:

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

The workaround is to remove the "mappedBy" attribute, which will cause the association to use the default join table strategy instead of a column on the target table. You can specify the name of the join table using the @JoinTable annotation.

The net effect of this change is that the "many" side of the relationship now determines how the relationship is persisted. Your java code needs to ensure that the List is updated properly, because Hibernate will now disregard the "one" side when flushing the entities.

If you still want to have the "one" side accessible in Java, map it with

@ManyToOne
@JoinColumn(name="...", insertable=false, updatable=false, nullable=false)


Do something like this:

@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);
        }
    }
}


You should try to specify OrderColumn on the owner of the association. Or in your mapping you put the owner on the child, the owner should be the parent (on a bidirectionnal association, the owner is the one which doesn't have the keyword mappedBy, here you put this keyword on the parent's class, then you mean the parent's class is not the owner)

In your children class you should have the keyword mappedBy on the parentCollection. But not on the childrenCollection.
And in your parent class you should have the annotation @JoinTable, something like this :

@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;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜