What is the best way to chain multiple optional parameters to a query in hibernate?
Doing something like this feels very clunky, but I don't see a better way to do it:
StringBuilder builder = new StringBuilder("SELECT a from address a WHERE ");
if(!StringUtil.isNullOrEmpty(streetName)) {
builder.append("a.streetName = :streetName AND ");
}
if(!StringUtil.isNullOrEmpty(houseNumber)) {
builder.append("a.houseNumber = :houseNumber AND ");
}
if(!StringUtil.isNullOrEmpty(city)) {
builder.append("a.city = :city AND ");
}
if(!StringUtil.isNullOrEmpty(countryCode)) {
builder.append("a.countryCode = :countryCode AND ");
}
String sql = builder.substring(0, builder.length() - 4); //remove trailing 'AND'
TypedQuery<AddressEntity> query = entityManager.createQuery(sql, AddressEntity.class);
if(!StringUtil.isNullOrEmpty(streetName)) {
query.setParameter("streetName", streetName);
}
if(!StringUtil.isNullOrEmpty(houseNumber)) {
query.setParameter("houseNumber", houseNumber);
}
if(!StringUtil.isNullOrEmpty(city)) {
query.setParameter("city", city);
}
if(!StringUtil.isNullOrEmpty(countryCode)) {
query.setParameter("countryCode", countryCode);
}
return query.getResultList();
You could use a parameter map...
private static Map<String, Object> parameters = new HashMap<>();
public static void main(String[] args) {
parameters.put("streetName", "Linz");
parameters.put("houseNumber", 1);
String sql = parameters.entrySet().stream().map(e -> "a." + e.getKey() + " = :" + e.getKey()).collect(Collectors.joining(" AND "));
TypedQuery<AddressEntity> query = entityManager.createQuery(sql, AddressEntity.class);
parameters.entrySet().stream().forEach(e -> query.setParameter(e.getKey(), e.getValue()));
return query.getResultList();
}
}