Reputation: 457
In JPA, the query is:
Query q = entityManager.createQuery("select o from Product o WHERE o.category = :value");
q.setParameter("category", category);
How can I set category to any category in JPA? So if the null category passed, I simple ignore the category parameter, select all products.
Upvotes: 17
Views: 23290
Reputation: 145
The thing you are trying to achieve is counter intuitive in terms of design pattern. Let's think of the problems in SQL terms ignoring all JPA and other.
The corresponding SQL query of your JPQL looks like below
SELECT o.* FROM product o WHERE o.category = 'SOME_CAT';
Now if you pass null instead of category SOME_CAT
the SQL would be like
SELECT o.* FROM product o WHERE o.category IS NULL;
There is no SQL standard to invert the result set altering param value unless your SQL looks like following
SELECT o.* FROM product o WHERE o.category IS NOT NULL;
The similar JPQL will look like
SELECT o FROM Product o WHERE o.category <> :param
You can see that we need to invert the logical operation instead of manipulating the param. There is no standard way to achive this behavior unless you build JPQL dynamically with if else condition.
I would prefer a separate method handler one for filtering with category and other for listing all regardless of category.
Upvotes: 0
Reputation: 7097
Pascal Thivent gave pretty good answer recommending using Criteria
. However the Criteria
in his answer is pure Hibernate
criteria. Using JPA Criteria
example:
private List<Result> getProduct(String category) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Product> criteria = builder.createQuery(Product.class);
Root<Product> productRoot = criteria.from(Product.class);
if (category != null)
criteria.where(builder.equal(productRoot.get("category"), category))
}
entityManager.createQuery(criteria).getResultList();
}
Upvotes: 0
Reputation: 49
To archive parameters become optional you can write a query without having to use the Criteria API:
select o from Product o WHERE :value is null or :value='' or o.category = :value
Upvotes: 4
Reputation: 640
You are right almost with small change.
Query query = entityManager.createQuery("select o from Product o WHERE o.category = :value");
query.setParameter("value", category);
in setParamater "value" (exact text) should match with ":value" in query.
Upvotes: 2
Reputation: 277
How can I set category to any category in JPA? So if the null category passed, I simple ignore the category parameter, select all products.
You can set the category to "%". if (category == null) query.setParameter("category", "%"); else query.setParameter("category", category);
Upvotes: 1
Reputation: 570295
How can I set category to any category in JPA? So if the null category passed, I simple ignore the category parameter, select all products.
You'll have to build the query dynamically here. With HQL (this is a simplified example):
Map<String, Object> params = new HashMap<String, Object>();
StringBuffer hql = new StringBuffer("from Product p");
boolean first = true;
if (category != null) {
hql.append(first ? " where " : " and ");
hql.append("p.category = :category");
params.put("category", category);
}
// And so on...
Query query = session.createQuery(hql.toString());
Iterator<String> iter = params.keySet().iterator();
while (iter.hasNext()) {
String name = iter.next();
Object value = params.get(name);
query.setParameter(name, value);
}
List results = query.list()
But, actually, my recommendation would be to use the Criteria API here:
Criteria criteria = session.createCriteria(Product.class);
if (category != null) {
criteria.add(Expression.eq("category", category);
}
// And so on...
List results = criteria.list();
Much simpler for complicated dynamic queries.
Upvotes: 19
Reputation: 262474
SELECT * FROM PRODUCT WHERE CATEGORY=*
I think you are new to SQL, too.
WHERE CATEGORY = *
does not mean "any category" (it is not even valid SQL).
In both SQL and JPA, you would just not have the WHERE
clause at all if you want any category (or in SQL you could have WHERE CATEGORY IS NOT NULL
).
Upvotes: 0