尝试在不使用 order by 子句的情况下存储命名查询,获取查询字符串并在运行时按子句段添加 order by 子句。
布莱恩·菲尔兹(Brian Fields)在他的博客中解释了这一点:http://brainfields.blogspot.com/2009/08/order-by-in-hibernate-named-queries.html
我已经为我的项目打包了这个想法:
private static final Pattern badQueryPattern = Pattern.compile("[^\\p{ASCII}]*");
public static String getNamedQueryString(EntityManager em, String queryName) throws SQLException {
Query tmpQuery = em.createNamedQuery(queryName);
SQLQuery sqlQuery = tmpQuery.unwrap(SQLQuery.class);
String queryString = sqlQuery.getQueryString();
if (badQueryPattern.matcher(queryString).matches()) {
throw new SQLException("Bad query string.");
}
return queryString;
}
public static Query getNamedQueryOrderedBy(EntityManager em, String queryName, Map<String, Boolean> columnNames) throws SQLException {
StringBuilder sb = new StringBuilder();
sb.append(ORDER_BY_CLAUSE_START);
int limit = columnNames.size();
int i = 0;
for (String columnName: columnNames.keySet()) {
sb.append(columnName);
if (columnNames.get(columnName))
sb.append(" ASC");
else
sb.append(" DESC");
if (i != (limit - 1)) {
sb.append(", \n");
}
}
Query jpaQuery = em.createNativeQuery( getNamedQueryString(em, queryName)
+ sb.toString()
);
return jpaQuery;
}