Why are there two queries in one annotation? - spring-boot

Below is an example from the Spring Data and Neo4j documentation, which demonstrates the usage of cypher queries.
// returns a Page of Actors that have a ACTS_IN relationship to the movie node with the title equal to movieTitle parameter.
#Query(value = "MATCH (movie:Movie {title={0}})<-[:ACTS_IN]-(actor) RETURN actor", countQuery= "MATCH (movie:Movie {title={0}})<-[:ACTS_IN]-(actor) RETURN count(actor)")
Page<Actor> getActorsThatActInMovieFromTitle(String movieTitle, PageRequest page);
what's the use of the second query "countQuery=..."? Does it play any role in this query?

The usage is mentioned in the documentation here. The relevant section:
If it is required that paged results return the correct total count,
the #Query annotation can be supplied with a count query in the
countQuery attribute. This query is executed separately after the
result query and its result is used to populate the number of elements
on the Page.

Related

Criteria Query to retrieve data from DB using specification and predicate

I have two tables (user, vehicles) and i want to write criteria query to retrieve data from db using criteria query specification and predicate to both Join Tables.
select ur.id, count (ur.vehicle_FK) from user so
inner join VEHICLE vhe on vhe.user_id_FK = ur."ID"
group by ur.id, vhe.user_id_FK;
How to implement it using criteria query ??
Try something like this :
Criteria criteria = session.createCriteria(User.class, "user");
criteria.createAlias("user.vehicle_FK", "vehicle", Criteria.INNER_JOIN);
criteria.setProjection(
Projections.projectionList().add(Projections.groupProperty("user.id"))
.add(Projections.countDistinct("user.id")));
Parameters in Criteria Queries
The following query string represents a JPQL query with a parameter:
SELECT c FROM Country c WHERE c.population > :p
An equivalent query can be built using the JPA criteria API as follows:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Country> q = cb.createQuery(Country.class);
Root<Country> c = q.from(Country.class);
ParameterExpression<Integer> p = cb.parameter(Integer.class);
q.select(c).where(cb.gt(c.get("population"), p));
The ParameterExpression instance, p, is created to represent the query parameter. The where method sets the WHERE clause. As shown above, The CriteriaQuery interface supports method chaining. See the links in the next sections of this page for detailed explanations on how to set criteria query clauses and build criteria expressions.
You can find more examples here
https://www.objectdb.com/java/jpa/query/criteria
Remember to post an answer when you find one! :)

Spring JPA - How to create a Pageable with a NativeQuery?

I try to do the following inside a Spring Boot application : create a native query and page it so it can returns a page of a given number of elements from a #RestController.
Here's the snippet of my code, where em is the #PersistanceContext EntityManager, and the repository method is the following, knowing that queryString is the native query :
Query searchQuery = em.createNativeQuery(this.queryString, MyEntity.class);
List<MyEntity> resultsList = searchQuery.getResultList();
return new PageImpl<>(resultsList, PageRequest.of(index,size), resultsList.size());
My problem is that the Page returned has a content of the complete query result, not a content of the size of size parameter inside the PageRequest.of.
Has anybody faced the same issue and could give a working example on how to paginate a nativeQuery please ?
Thanks for your help
You are mixing Spring Data JPA (Pageable) with JPA EntityManager. You can't do that. If you are already using a native query then simply put the pagination in the query. You can use what your database supports, for example the standard:
SELECT [a_bunch_of_columns]
FROM dbo.[some_table]
ORDER BY [some_column_or_columns]
OFFSET #PageSize * (#PageNumber - 1) ROWS
FETCH NEXT #PageSize ROWS ONLY;
this is example of using native query with pagination:
#Query("SELECT c FROM Customer As c INNER JOIN Offer as f on f.id=c.specialOffer.id inner join User As u on u.id=f.user.id where u.id=?1 And c.status=?2")
Page<Customer> getAllCustomerToShop(Integer shopId,String status,Pageable pageable)
and then you can call it as:
getAllCustomerToShop(shopId,"status",PageRequest.of(index, PAGE_SIZE));
Modify your code as follows
Query searchQuery = em.createNativeQuery(this.queryString, MyEntity.class)
.setFirstResult(pageable.getPageNumber() * pageable.getPageSize())
.setMaxResults(pageable.getPageSize());

Elasticsearch query not returning expected results for multiple should filters

I am performing an Elasticsearch query using the high-level-rest-api for Java and expect to see records that are either active or do not have a reference id. I'm querying by name for the records and if I hit the index directly with /_search?q=, I see the results I want.
Is my logic correct (pseudo-code):
postFilters.MUST {
Should {
MustNotExist {referenceId}
Must {status = Active}
}
Should {
MustNotExist {referenceId}
Must {type = Person}
}
}
What I get are records that are active with a reference id. But, I want to include records that also do not have a referenceId, hence why I have MustNotExist {referenceId}.
For simplicity, the second Should clause can be dropped (for testing) as the first one is not working as expected by itself.
In my case, I had to use a match query instead of a term query because the value I was querying for was not a primitive or a String. For example, the part where Must, type = Person, Person was an enum, and so looking for "Person" was not quite right, whereas match allowed it to "match".

How to set limit for a hibernate query

How can I set a limit to this hql query? When I add the limit keyword in the query, an error is thrown.
#Query("from voucher v where v.voucherType.typeDescription = :typeDescription and v.denomination = :denomination")
public List<Voucher> findByVoucherTypeAndDenomination(#Param("typeDescription") String typeDescription,#Param("denomination") BigDecimal denomination);
When you call your query add the following:
.setFirstResult(firstResult).setMaxResults(limit);
setFirstResult is the (optional) offset, setMaxResults is the limit.
UPDATE
Docs:
http://docs.jboss.org/hibernate/orm/3.6/javadocs/org/hibernate/Query.html#setMaxResults(int)
If you use entityManager, it can be like:
entityManager.createQuery("yourQuery").setFirstResult(0).setMaxResults(5);
You can use two method of Query object.
setFirstResult() // offset
setMaxResults() // limit
but you can not use it in HQL because limit is database vendor dependent so hibernate doesn't allow it through hql query
Limit was never a supported clause in HQL. You are meant to use setMaxResults().

MongoTemplate method or query for finding maximum values from a fileds

I am using MongoTemplate for my DB operations. Now i want to fetch the maximum fields values from the selected result. Can someone guide me how i write the query so that when i pass the query to find method it will return me the desired maximum fields of document . Thanks in advance
Regards
You can find "the object with the maximum field value" in spring-data-mongodb. Mongo will optimize sort/limit combinations IF the sort field is indexed (or the #Id field). Otherwise it is still pretty good because it will use a top-k algorithm and avoid the global sort (mongodb sort doc). This is from Mkyong's example but I do the sort first and set the limit to one second.
Query query = new Query();
query.with(new Sort(Sort.Direction.DESC, "idField"));
query.limit(1);
MyObject maxObject = mongoTemplate.findOne(query, MyObject.class);

Resources