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, everything works fine. But I can't make it reorder elements in the List and save the new order to the database.
@OrderColumn is used to store list index. As list is ordered collection, so to maintain the list index there can be a column in database and while inserting the data, list index will be stored in that column. For this the property in entity should be annotated with. @OrderColumn (name="column-name")
@Column. Let's start with the @Column annotation. It is an optional annotation that enables you to customize the mapping between the entity attribute and the database column.
@Entity annotation marks this class as an entity. @Table annotation specifies the table name where data of this entity is to be persisted. If you don't use @Table annotation, hibernate will use the class name as the table name by default.
We can use the @Basic annotation to mark a basic type property: @Entity public class Course { @Basic @Id private int id; @Basic private String name; ... } In other words, the @Basic annotation on a field or a property signifies that it's a basic type and Hibernate should use the standard mapping for its persistence.
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); } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With