What is the preferred way for maintaining the order of a collection while persisting and also while retrieving from database?
I know that @OrderBy is more of a in-memory sorting that might work in retrieving only when you presist the rows in the order of column you chose.
Let's say I chose to use a column backed by a database sequence, will hibernate make sure that elements in collection are persisted in the same order as in collection (say List).
Any thought?
Let’s say I have a class A which has one-to-many relationship with class B. B has a primary key field, ‘Id’, which is backed by a sequence in DB.
Class A {
List<B> bList;
}
I always wanted to retain the order of elements B in A like below:
bList = { b1, b2, b3 }
One way to achieve is using @OrderBy (“Id ASC”). This would work only when the list B is persisted in the order as below:
----------------
Id ----bValue
----------------
1------ b1
2------ b2
3-------b3
------------------
When we retrieve since it is ordered by Id, the order is maintained.
Let’say the collection B is persisted in the following way:
----------------
Id ----bValue
----------------
1------ b2
2------ b1
3-------b3
------------------
When we retrieve, the order of list B go for a toss (since it is order by Id column). So my question, if the collection B always persist in the same order as it appears in the list or not.
When use sorting, Hibernate will load the associated Book entities from the database and use a Java Comparator to sort them in memory. That is not a good approach for huge Sets of entities. Ordering uses an ORDER BY clause in the SQL statement to retrieve the entities in the defined order.
The annotation @OrderBy Specifies the ordering of the elements of a collection valued association or element collection at the point when the association or collection is retrieved.
@OrderColumn annotation specifies a column that should maintain the persistent order of a list. The persistence provider maintains the order and also updates the ordering on insertion, deletion, or reordering of the list. This annotation can be used on @OneToMany or @ManyToMany relationship or on @ElementCollection .
@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")
OrderBy adds an order by clause to the generated SQL to order the members of the retrieved collection by a column of the table of the target entity:
@OrderBy("lastname ASC")
public List<Student> students;
will generate a SQL query like
select ... order by student.lastname ASC
OrderColumn defines the name of an additional column in the table, containing the index of the entity in the list. If you change the ordering of the elements in the list, Hibernate will change the value of this column. And if your students have 0, 3, and 5 as values in this column, the list will be
[student0, null, null, student3, null, student5]
This is well described in the javadoc of those 2 annotations.
EDIT:
The order in which B identifiers are assigned depends on how you persist these B instances:
session.save()
, of session.saveOrUpdate()
, this assigns an ID to the entity, so calling it for b1, b2 and b3 will respect the orderflush()
)So if you want the list to hold b1, b2 and b3 in this order, regardless of the way those are persisted, your best bet is to add an @OrderColumn
annotation to the collection. Hibernate will automatically populate this column with 0 for b1, 1 for b2 and 2 for b3. And when you'll reload the parent entity, They will be in the same order in the list.
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