I came across recently was trying to order a Hibernate Criteria Query by two columns of equal importance. Basically what I mean is, if I have a table where one column is a date (createdOnDate) and the other is a date (modifiedOnDate), I’d like to compare all dates in the orderBy clause from Organization object.
for this i tried like this:
session.createCriteria(Organization.class).addOrder(Order.desc("modified_date")).addOrder( Order.desc("created_date") ).list();
But it is sorting all the organizations first based on the modified_date and then again it is sorting using created_date. This means a modified record could appear before any createdOn records, even if the createdOnDate is earlier.
I need sorting happens simaltaneously with created_date & modified_date.
Please help for this.
Thanks in advance.
You can use "COALESCE()" function in sql to take value from two column when first one will be null than it will take second column,
ORDER BY COALESCE( alias_1.modified_date, alias_1.created_date ) ASC;
So it means if value present in "modified_date" column take for sorting if not present than take from "created_date" for sorting.
In hibernate criteria for COALESCE() function i think there is no Order Bean so you can extend and write your own implementation.
Just like this, if wrong please correct me.
public class CoalesceOrder extends Order {
private String[] properties;
protected CoalesceOrder(boolean ascending, String... properties) {
super(properties.toString(), ascending);
this.properties = properties;
}
@Override
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
StringBuilder fragment = new StringBuilder();
StringBuilder exp = new StringBuilder();
fragment.append("COALESCE(");
SessionFactoryImplementor factory = criteriaQuery.getFactory();
for (int j = 0; j < this.properties.length; j++) {
String propertyName = this.properties[j];
String[] columns = criteriaQuery.getColumnsUsingProjection(
criteria, propertyName);
Type type = criteriaQuery.getTypeUsingProjection(criteria,
propertyName);
StringBuilder fragForField = new StringBuilder();
for (int i = 0; i < columns.length; i++) {
final StringBuilder expression = new StringBuilder();
boolean lower = false;
if (super.isIgnoreCase()) {
int sqlType = type.sqlTypes(factory)[i];
lower = sqlType == Types.VARCHAR || sqlType == Types.CHAR
|| sqlType == Types.LONGVARCHAR;
}
if (lower) {
expression.append(
factory.getDialect().getLowercaseFunction())
.append('(');
}
expression.append(columns[i]);
if (lower)
expression.append(')');
fragForField.append(expression.toString());
if (i < columns.length - 1)
fragForField.append(", ");
}
exp.append(fragForField.toString());
if (j < properties.length - 1)
exp.append(", ");
}
exp.append(")");
fragment.append(factory.getDialect().renderOrderByElement(
exp.toString(), null, super.isAscending() ? "asc" : "desc",
factory.getSettings().getDefaultNullPrecedence()));
return fragment.toString();
}
public static Order asc(String... properties) {
return new CoalesceOrder(true, properties);
}
public static Order desc(String... properties) {
return new CoalesceOrder(false, properties);
}
}
you can add Order now like
criteria.addOrder(CoalesceOrder.desc("modified_date", "created_date"));
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