I\'m trying to use the @OrderColumn
annotation with Hibernate 3.5
@OneToMany(mappedBy = \"parent\",fetch=FetchType.EAGER, cascade=CascadeType.AL
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;
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);
}
}
}
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)