Reputation: 23
I try to sort a list of Items for a customer by ordered Date. The Date is only avalable through Item.orderPositions.order.orderDate . But @IndexedEmbedded doesn't work. There's no Exeption or Error but the result is only sorted by HS-logic.
@Entity
@Indexed
public class Item{
@Id
private long id;
@Field(index = Index.YES, store = Store.YES, analyse = Analyse.YES, analyser = @Analyzer(definition = Constant.ANALYSER))
private String description;
@OneToMany(mappedBy = "item")
@IndexedEmbedded
private List<OrderPosition> orderPositions;
@ManyToOne
@IndexedEmbedded
private Company company;
//getter&setter
}
@Entity
public class OrderPosition{
@Id
private long id;
@ManyToOne
private Item item;
@ManyToOne
@IndexedEmbedded
private Order order;
//getter&setter
}
@Entity
public class Order{
@Id
private long id;
@ManyToOne
private Customer customer;
@Field(index = Index.NO, store = Store.NO, analyze = Analyze.NO)
@SortableField
private String orderDate;
//getter&setter
}
@Entity
public class Company{
@Id
private long id;
@Field(index = Index.NO, store = Store.NO, analyze = Analyze.NO)
@SortableField
private String name;
//getter&setter
}
If I sort the List by Item.company.name it works fine.
queryService.buildFullTextQuery("searchText", Item.class, "description", "company.name").getResultList();
If I sort the List by Item.orderPosition.order.orderDate it's sorted by default(HS-logic)
queryService.buildFullTextQuery("searchText", Item.class, "description", "orderPositions.order.orderDate").getResultList();
I build the FullTextQuery this way:
public FullTextQuery buildFullTextQuery(@NonNull String searchText, @NonNull Class<?> clazz, @NonNull String... fields) throws Exception {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(getEntityManager());
QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(clazz).get();
Query query = qb.keyword().onField(fields[0]).matching(searchText).createQuery();
SortField sortField = new SortField(fields[1], SortField.Type.STRING, false);
Sort sort = new Sort(sortField);
return fullTextEntityManager.createFullTextQuery(query, clazz).setSort(sort);
}
I think HS can't find the association for @OneToMany. Is there a way to solve this prob?
Thank you in advance
Upvotes: 0
Views: 412
Reputation: 9977
I can't tell you what's going on exactly without the results of your queries, but you're definitely doing something wrong here: you are trying to sort on a multi-valued field. One item is linked to multiple orders, each having its own date. So there is multiple dates per item.
When you ask to compare two items that each have three dates, what should Hibernate Search do? Compare only the latest dates? Compare only the earliest dates? You didn't say, so your query is bound to return inconsistently ordered results.
Thing is, there is no way to tell Hibernate Search which value to pick in multi-valued fields, so your easiest way out is to explicitly create a single-valued field to sort on.
For instance, you could add a getter on Item
to return the latest order, and add the @IndexedEmbedded
there:
@Entity
@Indexed
public class Item{
@Id
private long id;
@Field(index = Index.YES, store = Store.YES, analyse = Analyse.YES, analyser = @Analyzer(definition = Constant.ANALYSER))
private String description;
@OneToMany(mappedBy = "item")
@IndexedEmbedded
private List<OrderPosition> orderPositions;
@ManyToOne
@IndexedEmbedded
private Company company;
@javax.persistence.Transient
public Order getLatestOrder() {
Order latestOrder;
// ... compute the latest order ...
return latestOrder;
}
//getter&setter
}
Then sort on latestOrder.orderDate
and you should be good.
Upvotes: 1