Reputation: 561
I'm trying to print ordered list after persisting it and retrieving.
My Entities:
@Entity
public class News {
@Id @GeneratedValue
private Long id;
private String content;
@OneToMany(cascade = CascadeType.ALL)
@OrderBy("likes DESC")
private List<Comment> comments = new LinkedList<>();
//------------------
}
@Entity
public class Comment {
@Id
@GeneratedValue
private Long id;
private String content;
private int likes;
}
Main method snippet:
tx.begin();
{
// persist
News n1 = new News("Super news!!");
Comment c1 = new Comment("comment 1", 1);
Comment c2 = new Comment("comment 2", 200);
Comment c3 = new Comment("comment 3", 10);
n1.addComment(c1);
n1.addComment(c2);
n1.addComment(c3);
em.persist(n1);
// find
News news = em.find(News.class, n1.getId());
for (int i = 0; i < news.getComments().size(); i++) {
System.err.println(news.getComments().get(i).getLikes());
}
}
tx.commit();
The result printed in declaration order (1 -> 200 -> 10) and I expect (200 -> 10 -> 1). Can somebody help with this?
Upvotes: 2
Views: 1428
Reputation: 641
@OrderBy
is applied when sql query is executed. In your case the data is already in memory so sql query is not executed. You can try using @Sort
annotation that apply sorting in memory. Depending on your use case it may not be efficient if your list is big.
@Sort(type = SortType.COMPARATOR, comparator = CommentsComparator.class)
EDIT: @Sort is a hibernate specific annotation. For pure JPA I think the collection (List) can be updated to some sorted collection like SortedSet if possible.
Upvotes: 1
Reputation: 2667
I guess that you are getting your entity from the entity manager and not from db, so you are getting the same object that you created (not sorted object). You should try to refresh caché before the em.find()
method:
em.getTransaction().begin();
em.persist(n1);
em.getTransaction().commit();
// Clear object
em.getEntityManagerFactory().getCache().evict(News.class, n1.getId());
// find
News news = em.find(News.class, n1.getId());
for (int i=0; i<news.getComments().size(); i++){
System.err.println(news.getComments().get(i).getLikes());
}
From Javadoc, the method:
<T> T find(java.lang.Class<T> entityClass, java.lang.Object primaryKey)
Find by primary key. Search for an entity of the specified class and primary key. If the entity instance is contained in the persistence context, it is returned from there.
I empathize the part that maybe is getting you troubles.
Upvotes: 3