how do size JPA to Criteriaquery - java

I have this Java code:
CriteriaBuilder qb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> cq = qb.createQuery(Long.class);
cq.select(qb.count(cq.from(MyEntity.class)));
cq.where(/*your stuff*/);
return entityManager.createQuery(cq).getSingleResult();
I would like to do this a criteria query:
SELECT COUNT(p),pa.nomPays FROM SessionPersonne s JOIN s.personne p ,
p.entreprise e , e.adresse a , a.localite l , l.pays pa , s.session session
WHERE size(s.passageCollection) > 0 GROUP BY pa.nomPays
but how do size(s.passageCollection) > 0 with the critical query ?
Thanks you.

This tutorial explains everything very well.
http://www.baeldung.com/jpa-pagination
Just in case link breaks i'll add a segment and add where the where should be put too
int pageNumber = 1;
int pageSize = 10;
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
countQuery.select(criteriaBuilder.count(countQuery.from(Foo.class)));
Long count = entityManager.createQuery(countQuery).getSingleResult();
CriteriaQuery<Foo> criteriaQuery = criteriaBuilder.createQuery(Foo.class);
Root<Foo> from = criteriaQuery.from(Foo.class);
CriteriaQuery<Foo> select = criteriaQuery.select(from);
select.where(criteriaBuilder.equal(fromRoot.get("entityColumb"), "bar")));
TypedQuery<Foo> typedQuery = entityManager.createQuery(select);
while (pageNumber < count.intValue()) {
typedQuery.setFirstResult(pageNumber - 1);
typedQuery.setMaxResults(pageSize);
System.out.println("Current page: " + typedQuery.getResultList());
pageNumber += pageSize;
}

You can obtain the SIZE for use in Criteria as follows
Expression<Integer> sizeExpr = qb.size(SessionPersonne_.passageCollection)
hence
qb.greaterThan(sizeExpr, 0);

Related

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

Select from a select statement using JPA Criteria API

I have the following sql statement :
select * from (select A.A_ID, (SELECT count(*) FROM X WHERE A.A_ID = X.A_ID) AS countX from A) where countX > 3 order by countX ;
How can I create this using JPA Criteria API ?
I know how to create the inner sql query it's just the outer one I couldn't figure out, this is how I created the inner one :
final CriteriaBuilder builder = getCriteriaBuilder();
final CriteriaQuery<A_DTO> criteriaQuery = builder.createQuery(A_DTO.class);
final Root<A> aRoot = criteriaQuery.from(A.class);
final Subquery<Long> xSubquery = criteriaQuery.subquery(Long.class);
final Root<X> xRoot = xSubquery.from(X.class);
final Expression<Long> xCount = builder.count(xRoot);
xSubquery.select(xCount);
xSubquery.where(builder.equal(xRoot.get(X_.a).get(A_.aID), aRoot.get(A_.aID)));
criteriaQuery.multiselect(aRoot.get(A_.aID), xSubquery.getSelection());
return getEntityManager().createQuery(criteriaQuery);

JPA CriteriaBuilder how to create join + like query

I have a SQL query:
SELECT s.*, p.name, p.code
FROM `stock` s
LEFT JOIN product p ON s.product_id = p.id
WHERE p.name LIKE "%q%"
And I need to create the query using criteriabuilder
I started so:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<Stock> stock = cq.from(Stock.class);
Path<String> path = stock.get(filter.getKey());//i have error here
String likeValue = wildCard + value + wildCard;
Predicate filterCondition = cb.conjunction();
filterCondition = cb.and(filterCondition, cb.like(path, likeValue));
Please help, how to do it better?
the selection is unclear. In SQL you select s.*, p.name, p.code, but in criteria you expect a Long?
your LEFT JOIN has not to be LEFT.
in criteria you've no join at all.
you should use metamodel, as a general advice.
I think you want all Stocks which contain at least one Product with name like %value%.
If my assumption is right:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Stock> cq = cb.createQuery(Stock.class);
Root<Stock> stock = cq.from(Stock.class);
Join<Stock, Product> product = stock.join(Stock_.products);
cq.select(stock);
cq.distinct(true);
cq.where(cb.like(product.get(Product_.name), "%" + value + "%");
return em.createQuery(cq).getResultList();

Zero items in typedQuery.resultList()

I need to get from DB items in a date range ("created"). Query is correct (i check it in HeidiSQL) and select right rows from DB, but typedQuery.resultList() always has 0 items.
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<CurrencyConvertionRate> criteriaQuery = criteriaBuilder.createQuery(CurrencyConvertionRate.class);
Root<CurrencyConvertionRate> root = criteriaQuery.from(CurrencyConvertionRate.class);
List<Predicate> criteria = new ArrayList<Predicate>();
<Timestamp>get(created)={}", criteriaBuilder.greaterThanOrEqualTo(root.<Timestamp>get("created"), dateFrom).toString());
log.debug("criteriaBuilder.lessThanOrEqualTo(root.<Timestamp>get(created), dateTo={}", criteriaBuilder.lessThanOrEqualTo(root.<Timestamp>get("created"), dateTo).toString());
log.debug("root.get(currencyCode).in(currencyList)={}", root.get("currencyCode").in(currencyList).toString());
criteria.add(criteriaBuilder.greaterThanOrEqualTo(root.<Timestamp>get("created"), dateFrom));
criteria.add(criteriaBuilder.lessThanOrEqualTo(root.<Timestamp>get("created"), dateTo));
criteria.add(root.get("currencyCode").in(currencyList));
CriteriaQuery<CurrencyConvertionRate> select = criteriaQuery.select(root);
select.where(criteriaBuilder.and(criteria.toArray(new Predicate[0])));
TypedQuery<CurrencyConvertionRate> typedQuery = entityManager.createQuery(select);
return typedQuery.getResultList();

How to do JPA query with Criteria Clause?

First I want to do a query like
"select count(*) from Post p where p.tag in (tagArray) "
where tagArray is "'tag1','tag2','tag3'".then I'd like to do a paginate query:
query.setFirstResult(int1).setMaxResult(int2);
I don't know how to write this query. I searched the posts ,can't find answers, so can anybody give me any advice? thanks.
Here's sample code:
// get an entity manager
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaManager");
EntityManager em = emf.createEntityManager();
// create query
Query query = em.createQuery("select count(*) from Post p where p.tag in (tagArray)") // use parameters here when necessary
.setFirstResult(int1)
.setMaxResults(int2);
// get result
query.getResultList();
Update:
If you want to create query by criteria, try this:
CriteriaBuilder builder = em.getCriteriaBuilder(); // em is as the same the the above
CriteriaQuery<Post> query = builder.createQuery(Post.class);
Root<Post> post = query.from(Post.class);
query.select(post).where(post.get("tag").in("tag1", "tag2", "tag3")); // or pass a tag collection to `in` method
TypedQuery<Post> typedQuery = em.createQuery(query);
List<Post> results = typedQuery.setFirstResult(int1).setMaxResults(int2)
.getResultList();
Thank you very much! Following your instruction, I've done it like this,a little complicated.
public List<Post> findPostBySitePaged(Set sites, Page page) {
List<Post> result = new ArrayList<Post>();
if (sites == null || sites.size() == 0) return result;
try {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Long> cQuery = builder.createQuery(Long.class);
Root<Post> root = cQuery.from(Post.class);
CriteriaQuery<Long> select = cQuery.select(builder.count(root));
select.where(root.get("site").in(sites));
TypedQuery<Long> typedQuery = em.createQuery(select);
Long t = typedQuery.getSingleResult();
int tot = t.intValue() / page.getPageSize() + ((t.intValue() % page.getPageSize()) == 0 ? 0 : 1);
page.setTotal(tot);
CriteriaQuery<Post> criteriaQuery = builder.createQuery(Post.class);
root = criteriaQuery.from(Post.class);
criteriaQuery.select(root).where(root.get("site").in(sites)).orderBy(builder.desc(root.get("createDate")));
TypedQuery<Post> postQuery = em.createQuery(criteriaQuery);
postQuery.setFirstResult((page.getCurrent() - 1) * (page.getPageSize())).setMaxResults(page.getPageSize());
result = postQuery.getResultList();
} catch (Exception e) {
log.error(e.getMessage());
}
return result;
}

Categories

Resources