JPA Criteria api with CONTAINS function - java

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%';

Related

Using Java Predicates in MYSQL AND condition

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();

Run Query with IN clause using Criteria Builder

I need some help to run the query bellow, using the CriteriaBuilder aproach:
select count(*) from TABLE_VIEW_SEARCH where
person_ID in (select person_ID from TABLE_PERSON
where region_ID = 1001) and postal_cd ='AL';
I try this but it failed:
CriteriaBuilder cb = ..;
CriteriaQuery<Long> criteriaQuery= cb.createQuery(Long.class);
Root<ViewSearchEntity> from= criteriaQuery.from(ViewSearchEntity.class);
Subquery<Long> subQuery = criteriaQuery.subquery(Long.class);
Root<PersonEntity> subFrom = subQuery .from(PersonEntity.class);
subQuery .where(cb.equal(subFrom.get(PersonEntity_.region_ID ), region_ID ));
criteriaQuery.select(cb.count(from));
criteriaQuery.where(meFrom.in(subQuery );
TypedQuery<Long> query = getEntityManager().createQuery(criteriaQuery);
Long result = query.getSingleResult();
I reach a solution, basicaly I managed to do the join condition:
CriteriaBuilder cb = ..;
CriteriaQuery<Long> criteriaQuery= cb.createQuery(Long.class);
Root<ViewSearchEntity> from= criteriaQuery.from(ViewSearchEntity.class);
Predicate predicate1 = cb.equal(from.get(ViewSearchEntity.postal_cd),"AL");
Subquery<Long> subQuery = criteriaQuery.subquery(Long.class);
Root<PersonEntity> subRoot = subQuery.from(PersonEntity.class);
Join<PersonEntity, RegionEntity_> region= subRoot.join(RegionEntity_.region);
subQuery.select(region.get(RegionEntity_.regionId)).where(
cb.equal(subRoot.get(PersonEntity_.region), regionId));
Predicate predicateInClause = root.get(ViewSearchEntity_.postal_cd).in(subQuery);
return getEntityManager().createQuery(criteriaQuery.select(cb.count(root)).where(predicate1,predicateInClause)).getEntityManager().createQuery(criteriaQuery.select(cb.count(root)).where(predicate1,predicateInClause))
Something like this. I cannot give you a query, due to missing entity names. However, I recommend to read this Criteria API subselect
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery(TABLE_VIEW_SEARCH.class);
Root root = cq.from(TABLE_VIEW_SEARCH.class);
Subquery sub = cq.subquery(TABLE_PERSON.class);
Root subRoot = sub.from(TABLE_PERSON.class);
SetJoin<TABLE_PERSON, TABLE_VIEW_SEARCH> subViewSearch =
subRoot.join(TABLE_PERSON.tableViewSearch);
sub.select(cb.equal(subRoot.get(TABLE_PERSON.region_ID), 1001));
cq.where(cb.equal(root.get("postal_cd"), "AL"));
TypedQuery query = em.createQuery(cq);
List result = query.getResultList();
You can use this method, once you have metamodel generation dependency declared:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
</dependency>
Rebuild your project with maven after you add this dependency, and then you can do this:
EntityName_.attribute

CriteriaBuilder with criteria on the child associations . Hibernate

I have orders (id, name) with oneToMany to items (id, name):
How can I fetch only these orders which have items of name 'banana' with a CriteriaBuilder:
#Override
public Order orderQuery() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery criteriaQuery = cb.createQuery(Order.class);
Root root = criteriaQuery.from(Order.class);
root.fetch("items", JoinType.INNER);
CriteriaQuery d = criteriaQuery.select(root);
criteriaQuery.where(cb.equal(root.get("item.name"), "banana"));
return (Order)this.entityManager.createQuery(criteriaQuery).getSingleResult());
}
I get the error:
Unable to locate Attribute with the the given name [item.name] on
You need to use a Join. Something around these lines:
Join< Order ,Item> joinItems = root.join("items");
criteriaQuery.where(cb.equal(joinItems.get("item.name"), "banana"));
alternativly you can do something like:
criteriaQuery.where(cb.equal(root.get("items").get("name"), "banana"));

Build criteria query with joins and custom parameters

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.

jpa criteria builder writing simple query

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?

Categories

Resources