How to retrieve Page result using mongo template
I have a scenario like below :
final Pageable pageableRequest = PageRequest.of(offset, limit);
Criteria criteria = where("");
if (null != type) {
criteria = criteria.and("type").is(type);
}
if (null != revision) {
criteria = criteria.and("current_revision_data.data.revision_start").is(revision);
}
Query query = query(criteria).with(pageableRequest);
Page<Invoice> invoices = mongoTemplate.find(query, Invoice.class);
Could someone point me how to get page of the result?
EDIT : To be more specific the last line that is :
Page invoices = mongoTemplate.find(query, Invoice.class);
is a compilation failure.
I would like to get Paged results which I could not find using MongoTemplate
Thanks
Related
I have created in a Spring Boot project a dynamic function that builds dynamic JPA queries with pagination. The main and count query are built correctly at runtime, I have even tested them directly in DB and they work fine. The problem is when the count statement is executing, the query never respond and does not show error messages. The count query built at runtime takes 4565ms in SQLDeveloper tool.
I share a code snippet and an image of where the logs are stopped...
Page<T> resultPage;
....
//create main JPA query
Query mainQuery = coreEntityManager.createQuery(queryBuilder.toString(), resultClass);
//create count JPA query
Query countQuery = coreEntityManager.createQuery(countQueryBuilder);
//set pageable params
int pageNumber = pageable.getPageNumber();
int pageSize = pageable.getPageSize();
//set first result cursor in main query
mainQuery.setFirstResult((pageNumber) * pageSize);
//set max result values in main query
mainQuery.setMaxResults(pageSize);
//set parameters in queries
for (String key : parameterMap.keySet()) {
//main query
mainQuery.setParameter(key, parameterMap.get(key));
//count query
countQuery.setParameter(key, parameterMap.get(key));
}
//run main query
List<T> fooList = mainQuery.getResultList();
//check result
if (fooList == null || fooList.size() == 0) {
//if empty return
resultPage = new CustomPage<T>(new ArrayList<T>());
} else {
//if contains values return pageable values
Long size= (Long) countQuery.getSingleResult();
log.debug("Size result query: {}",size);
resultPage = new CustomPage<T>(fooList, pageable, size);
}
return resultPage;
I am trying to get details of Properties details from database using JPQL, Hear I am writing where condition like (properties.IsDeleted <> 'Y' or properties.IsDeleted IS NULL)
but, in JPQL query it is not getting 'Y', but, it is was showing like '?' symbol. this is the problem I am getting. please help me from this issue.
the below code is showing query like:-
select properties0_.property_id as col_0_0_,
properties0_.property_type as col_1_0_, properties0_.property_name as
col_2_0_, properties0_.property_area as col_3_0_,
properties0_.property_city as col_4_0_, properties0_.no_of_rooms as
col_5_0_ from iot_property properties0_ where
(properties0_.is_deleted<>? or properties0_.is_deleted is null) and
properties0_.property_id=6
In the above query in bold mark shows properties0_.is_deleted<>? ,but what I want is properties0_.is_deleted<>Y
why that "Y" is not assigned to that query. that I am not understanding.
will you please help me to solve this issue.
Thanks
CriteriaBuilder deviceBuilder = propertySession.getCriteriaBuilder();
CriteriaQuery<Object[]> userCriteriaQuery = deviceBuilder.createQuery(Object[].class);
Root<Properties> propertyRoot = userCriteriaQuery.from(Properties.class);
Path<Object> pathPropertyId = propertyRoot.get("propertyId");
Path<Object> pathpropertyType = propertyRoot.get("propertyType");
Path<Object> pathpropertyName = propertyRoot.get("propertyName");
Path<Object> pathpropertyArea = propertyRoot.get("propertyArea");
Path<Object> pathpropertyCity = propertyRoot.get("propertyCity");
Path<Object> pathnumberOfRooms = propertyRoot.get("numberOfRooms");
userCriteriaQuery.multiselect(pathPropertyId, pathpropertyType, pathpropertyName, pathpropertyArea,
pathpropertyCity, pathnumberOfRooms);
Predicate userRestriction = deviceBuilder.or(deviceBuilder.notEqual(propertyRoot.get("isDelete"), "Y"),
deviceBuilder.isNull(propertyRoot.get("isDelete")));
Predicate userRestriction2 = deviceBuilder
.and(deviceBuilder.equal(propertyRoot.get("propertyId"), propertyId));
userCriteriaQuery.where(deviceBuilder.and(userRestriction, userRestriction2));
Query<Object[]> deviceQuery = propertySession.createQuery(userCriteriaQuery);
List<Object[]> resultList =deviceQuery.getResultList();
for(Object[] objects : resultList) {
Integer dbPropertyId = (Integer) objects[0];
String dbPropertyType = (String) objects[1];
String dbpropertyName = (String) objects[2];
String dbpropertyArea = (String) objects[3];
String dbpropertyCity = (String) objects[4];
Integer dbNoOfRooms = (Integer) objects[5];
System.out.println(dbPropertyId);
System.out.println(dbPropertyType);
System.out.println(dbpropertyName);
System.out.println(dbpropertyArea);
System.out.println(dbpropertyCity);
System.out.println(dbNoOfRooms);
}
There is no such thing as "the final JPQL that ultimately gets translated to the final SQL with inserted paramerters". How a JPA implementation generates the SQL is down to it, and parameters, in general, will never be substituted into any String. SQL has generated from expression trees etc, not a String. This is a criteria query so for parameters it will show "?" on the console.
If you want param values inserting in then do it yourself since it only makes sense to you
I am using Spring boot JPA to below execute below query
select DELTA_TYPE,OPERATION_ID,COUNT(*) from ACTIVE_DISCREPANCIES ad group by DELTA_TYPE,OPERATION_ID
DELTA_TYPE,OPERATION_ID, etc may come from external system, in repository class I tried to execute native query
#Query(value="select OPERATION_ID,DELTA_TYPE,count(*) from ACTIVE_DISCREPANCIES ad group by ?1",nativeQuery = true)
public List<Object[]> groupByQuery(#Param("reconType") String recGroupColumns);
where recGroupColumns="DELTA_TYPE,OPERATION_ID" but didnt work as #param will split ','
Second option for me was criteria query
public List<Object[]> getReconGroupList() {
String recGroupColumns = "OPERATION_ID,DELTA_TYPE";
String[] arrStr = recGroupColumns.split(",");
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Object[]> query = criteriaBuilder.createQuery(Object[].class);
Root<ActiveDiscrepancies> adr = query.from(ActiveDiscrepancies.class);
query.groupBy(adr.get("operationId"), adr.get("deltaType"));
// query.groupBy(adr.get("deltaType"));
query.multiselect(adr.get("operationId"), adr.get("deltaType"), criteriaBuilder.count(adr));
TypedQuery<Object[]> typedQuery = entityManager.createQuery(query);
List<Object[]> resultList = typedQuery.getResultList();
return resultList;
}
Here how can I pass groupBy and multiselect dynamically?
Using projections we can solve this scenario, below is the code
Criteria criteria = getSession().createCriteria(ActiveDiscrepancies.class);
ProjectionList projectionList = Projections.projectionList();
for(String str : colList) {
projectionList.add(Projections.groupProperty(str));
}
projectionList.add(Projections.rowCount());
criteria.setProjection(projectionList);
List results = criteria.list();
getSession().close();
I have the following four tables:
SCHEDULE_REQUEST TABLE:
ID,
APPLICATION_ID (FK)
APPLICATION TABLE:
ID,
CODE
USER_APPLICATION TABLE:
APPLICATION_ID (FK),
USER_ID (FK)
USER TABLE:
ID,
NAME
Now I wanted to create a CriteriaBuilder where condition is to select ScheduleRequests for specified user Ids.
I have the following codes:
List<User> usersList = getSelectedUsers(); // userList contains users I wanted to select
CriteriaBuilder builder = getJpaTemplate().getEntityManagerFactory().getCriteriaBuilder();
CriteriaQuery<ScheduleRequest> criteria = builder.createQuery(ScheduleRequest.class);
Root<ScheduleRequest> scheduleRequest = criteria.from(ScheduleRequest.class);
criteria = criteria.select(scheduleRequest);
ParameterExpression<User> usersIdsParam = null;
if (usersList != null) {
usersIdsParam = builder.parameter(User.class);
params.add(builder.equal(scheduleRequest.get("application.userApplications.user"), usersIdsParam));
}
criteria = criteria.where(params.toArray(new Predicate[0]));
TypedQuery<ScheduleRequest> query = getJpaTemplate().getEntityManagerFactory().createEntityManager().createQuery(criteria);
// Compile Time Error here:
// The method setParameter(Parameter<T>, T) in the type TypedQuery<ScheduleRequest> is not
// applicable for the arguments (ParameterExpression<User>, List<User>)
query.setParameter(usersIdsParam, usersList);
return query.getResultList();
Can you please help me how to pass query filter to a relationship object?
I think what I did in "application.userApplications.user" is wrong?
Please really need help.
Thank you in advance!
Using the canonical Metamodel and a couple of joins, it should work. Try if you get some hints from the following pseudo-code (not tested):
...
Predicate predicate = cb.disjunction();
if (usersList != null) {
ListJoin<ScheduleRequest, Application> applications = scheduleRequest.join(ScheduleRequest_.applications);
ListJoin<Application, UserApplication> userApplications = applications.join(Application_.userApplications);
Join<UserApplication, User> user = userApplications.join(UserApplication_.userId);
for (String userName : usersList) {
predicate = builder.or(predicate, builder.equal(user.get(User_.name), userName));
}
}
criteria.where(predicate);
...
In order to understand Criteria Queries, have a look at these tutorials:
http://www.ibm.com/developerworks/java/library/j-typesafejpa/
http://docs.oracle.com/javaee/6/tutorial/doc/gjitv.html
The second link should also guide you on how to use Metamodel classes, that should be built automatically by the compiler / IDE.
I am running an aggregate function in java through hibernate and for some reason it is giving me this error:
INFO Binary:182 - could not read column value from result set: l_date; Column 'l_date' not found.
When I run the MySQL query the column names are l_date and logins and I can not figure out why it is not finding that.
I have tested the query in MySQL and verified that it does work. My function looks as follows.
public List<Logins> getUserLoginsByMonth() {
Session session = getSessionFactory().openSession();
ArrayList<Logins> loginList = null;
try {
String SQL_QUERY = "SELECT l_date as l_month, SUM(logins) as logins FROM (SELECT DATE_FORMAT(login_time, '%M') as l_date, COUNT(DISTINCT users) as logins FROM user_logins WHERE login_time > DATE_SUB(NOW(), INTERVAL 1 YEAR) GROUP BY DATE(login_time)) AS Z GROUP BY(l_month)";
Query query = session.createSQLQuery(SQL_QUERY);
List results = query.list();
for(ListIterator iter = results.listIterator(); iter.hasNext() ) {
Objects[] row = (Object[])iter.next();
System.out.println((Date)row[0}]);
System.out.println((BigInteger)row[1]);
}
}
catch(HibernateException e) {
throw new PersistenceDaoException(e);
}
finally {
session.close();
}
}
You need to add aliases as:
query.addScalar("l_month");
query.addScalar("logins");
and then call query.list();
It should work fine. addScalar is part of SqlQuery.