I have the following java predicate based code that gets a result list from my MYSQL DB:
Root<Person> from = query.from(Person.class);
CriteriaQuery<Person> selectQuery = query.select(from);
List<Person> searchResults = new ArrayList<>();
Predicate jobPredicate = createPersonJobPredicate();
Predicate agePredicate = createPersonAgePredicate(); //currently not used
selectQuery = selectQuery.where(jobPredicate);
searchResults =entityManager.createQuery(selectQuery).setFirstResult(searchRequest.getIndex()).setMaxResults(searchRequest.getSize()).getResultList();
What I want to do is change the above code so that the result list has to match both predicates - e.g. must be job - "doctor" AND age - 45
I have tried combining the predicates as such below, but this always only returns the job predicate:
selectQuery = selectQuery.where(jobPredicate).where(agePredicate);
How can I do so?
Try something like:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
Root<Person> personRoot = criteriaQuery.from(Person.class);
Predicate jobPredicate = criteriaBuilder.equal(personRoot.get("job"), "doctor");
Predicate agePredicate = criteriaBuilder.greaterThan(personRoot.get("age"), 45);
Predicate combinedPredicate = criteriaBuilder.and(jobPredicate, agePredicate);
criteriaQuery.where(combinedPredicate);
List<Person> searchResults =
entityManager.createQuery(criteriaQuery).getResultList();
Related
I want to implement Hibernate query with OrderBy clause. I tried this:
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<OrdersModel> query = builder.createQuery(OrdersModel.class);
Root<OrdersModel> root = query.from(OrdersModel.class);
query.select(root).orderBy(root.get("added"));
Query<OrdersModel> q = session.createQuery(query);
cdList = q.getResultList();
But I have to cast the .orderBy like this query.select(root).orderBy((List<javax.persistence.criteria.Order>) root.get("added"));
Do you know what is the proper way to implement this?
I tried also this:
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<OrdersModel> query = builder.createQuery(OrdersModel.class);
Root<OrdersModel> root = query.from(OrdersModel.class);
query.select(root);
query.orderBy(builder.desc(root.get("added")));
Query<OrdersModel> q = session.createQuery(query).setMaxResults(5);
cdList = q.getResultList();
But the rows order are not displayed properly. The list is not properly sorted.
I need to build following query using JPA and criteria query but I stuck on join conditions. The query is:
SELECT p.*
FROM output cu
JOIN user ur ON cu.id = ur.id AND cu.key = ur.key
JOIN product p ON cu.id = p.id AND cu.key = p.key
WHERE p.refreshtimestamp IS NOT NULL AND cu.active = true
So far I have following, but how to apply join conditions:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Output> cq = cb.createQuery(Output.class);
Root<Output> output= cq.from(Output.class);
Join<Output, User> user = output.join("user", JoinType.INNER);
Join<User, Product> product = user.join("product", JoinType.INNER);
Any help will be appreciated
Following should help.
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Product> criteria = builder.createQuery(Product.class);
Root<Output> outputRoot = criteria.from(Output.class);
Root<User> userRoot = criteria.from(User.class);
Root<Product> productRoot = criteria.from(Product.class);
Predicate[] predictes = {
builder.equal(outputRoot.get("id"), userRoot.get("key")),
builder.equal(productRoot.get("id"), userRoot.get("key")),
builder.notEqual(productRoot.get("refreshtimestamp"), null), // not sure about null
builder.equal(outputRoot.get("active"), true)
};
criteria.select(productRoot);
criteria.where(builder.and(predicates));
Although this would produce cross joins query, it will work because of where clause making it work like inner join as you require.
Code:
List<Predicate> conditionsList = new ArrayList<Predicate>();
Predicate onStart = criteriaBuilder.greaterThanOrEqualTo(criteriaRoot.get("insertDateTime"), startTradeDate);
Predicate onEnd = criteriaBuilder.lessThanOrEqualTo(criteriaRoot.get("insertDateTime"), endTradeDate);
conditionsList.add(onStart);
conditionsList.add(onEnd);
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
CriteriaQuery<MyClass> criteriaQuery =
criteriaBuilder.createQuery(MyClass.class);
Root<MyClass> criteriaRoot = criteriaQuery.from(MyClass.class);
criteriaQuery.select(criteriaRoot).where(conditionsList);
The last line above doesn't compile because its expecting the conditionsList object to be a List of Boolean not list of Predicate.
Please advise me on the correct way of adding predicates above to the hibernate criteria?
Convert the List<Predicate> into an array Predicate[] like this:
criteriaQuery.select(criteriaRoot).where(conditionsList.toArray(new Predicate[] {}));
I want to select from database entities with certain price and with certain type but the result list is empty using criteria builder.I came to this code
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Object> criteriaQuery = criteriaBuilder.createQuery();
Root<Advert> from = criteriaQuery.from(Advert.class);
Predicate predicate1 = criteriaBuilder.ge(from.get("price"), x1);
Predicate predicate2 = criteriaBuilder.le(from.get("price"), x2);
Predicate predicate4 = criteriaBuilder.like(from.get("type"), type);
criteriaQuery.where(criteriaBuilder.and(predicate1, predicate2, predicate4));
TypedQuery<Object> typedQuery = em.createQuery(criteriaQuery);
List<Object> resultList = typedQuery.getResultList();
But the it returns empty List.How to rewrite it correctly?
I'm trying to crete Criteria API query with CONTAINS function(MS SQL):
select * from com.t_person where contains(last_name,'xxx')
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
Root<Person> root = cq.from(Person.class);
Expression<Boolean> function = cb.function("CONTAINS", Boolean.class,
root.<String>get("lastName"),cb.parameter(String.class, "containsCondition"));
cq.where(function);
TypedQuery<Person> query = em.createQuery(cq);
query.setParameter("containsCondition", lastName);
return query.getResultList();
But getting exception:
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node:
Any help?
If you want to stick with using CONTAINS, it should be something like this:
//Get criteria builder
CriteriaBuilder cb = em.getCriteriaBuilder();
//Create the CriteriaQuery for Person object
CriteriaQuery<Person> query = cb.createQuery(Person.class);
//From clause
Root<Person> personRoot = query.from(Person.class);
//Where clause
query.where(
cb.function(
"CONTAINS", Boolean.class,
//assuming 'lastName' is the property on the Person Java object that is mapped to the last_name column on the Person table.
personRoot.<String>get("lastName"),
//Add a named parameter called containsCondition
cb.parameter(String.class, "containsCondition")));
TypedQuery<Person> tq = em.createQuery(query);
tq.setParameter("containsCondition", "%näh%");
List<Person> people = tq.getResultList();
It seems like some of your code is missing from your question so I'm making a few assumptions in this snippet.
You could try using the CriteriaBuilder like function instead of the CONTAINS function:
//Get criteria builder
CriteriaBuilder cb = em.getCriteriaBuilder();
//Create the CriteriaQuery for Person object
CriteriaQuery<Person> query = cb.createQuery(Person.class);
//From clause
Root<Person> personRoot = query.from(Person.class);
//Where clause
query.where(
//Like predicate
cb.like(
//assuming 'lastName' is the property on the Person Java object that is mapped to the last_name column on the Person table.
personRoot.<String>get("lastName"),
//Add a named parameter called likeCondition
cb.parameter(String.class, "likeCondition")));
TypedQuery<Person> tq = em.createQuery(query);
tq.setParameter("likeCondition", "%Doe%");
List<Person> people = tq.getResultList();
This should result in a query similar to:
select p from PERSON p where p.last_name like '%Doe%';