Pagination with ordered data with hibernate - java

Using hql in hibernate we can do pagination on a table data using below, but below will return first 5 data records in the table.
String SQL_QUERY = "FROM Order order";
Query query = session.createQuery(SQL_QUERY);
query.setFirstResult(1);
query.setMaxResults(5);
But how can i do the pagination on a ordered data on a table for example an ordered data set by a order_id ?

Not sure what you're asking, but just add order by clause in your query, and calculate first result based on page. Something like this
String HQL_QUERY = "FROM Order o order by o.id";
Query query = session.createQuery(HQL_QUERY);
// page size
query.setMaxResults(5);
// page 1
query.setFirstResult(1);
// page 2
query.setFirstResult(6);
...

Related

How to get data from raw query in spring boot?

I have a query:
Query q = em.createNativeQuery("select DISTINCT id, rating, random() as ordering FROM table\n" +
" WHERE id not in (1,2) ORDER BY ordering LIMIT 10");
List data = q.getResultList();
Every element of this list is array like object:
I want to retrieve that "8" and "16" and compose a comma separated string (to use it in my query in "not in" section in future):
for (Object x : data) {
System.out.println(Arrays.asList(x).get(0));
}
But it produces strings:
[Ljava.lang.Object;#ee93cd3
[Ljava.lang.Object;#62f3c3e1
I don't know how to get that IDs ("8" and "16")
1.I think this is what you are looking for...
Convert JPA query.getResultList() to MY Objects.
or
List<Object[]> rows = q.getResultList(); for (Object[] row : rows) { System.out.println(row[0]); }
in this line
List<Object[]> data = q.getResultList();
data is list of Object of form
[ [1,233, 0.000333], [1,233, 0.000333] ]
for (Object[] x : data) {
// x is [1,233, 0.000333]
System.out.println(x[0]);
}
If I understood it correctly, you are looking for comma separated string of ID's.
If so, then follow these steps might help you to solve the issue.
Create a constructor in table which has only one parameter ID. (If you want you can add more parameters as well but make sure the value which you want it must be in constructor as well as in query.)
Write sql query and execute it.
It returns result and gather it in List which contains the object of the table.
Get the string
dataList.stream().map(obj -> obj.getId()).collect(Collectors.joining(", "))
This will give you the comma separated string.

Getting the occurrence of values using JpaRepository Queries

I have a class named Submission and another SubmissionDAO for the repository. The submission class has a number of fields such as id, author, title,...
What I want to do is search through the database and get a list of (count, author) pairs for each author value in the database.
I made a query
#Query(value = "select author, count(*) from submissions GROUP BY author order by count(author) desc", nativeQuery = true)
List<Submission> findByAuthorOccurance();
Obviously, this doesn't work because it can't put the count value in the Submission object.
My question is how would I go about getting this pair of values back to my controller?
I've tried searching but nothing comes up.
In case anyone comes here in the future for whatever reason, I figured my problem out.
When you specify a range of data points to get from the query (ie author and count), it groups the values into object arrays (Object[]) and puts those in a normal List.
So my code ended up being like this:
#Query(value = "select author, count(*) from submissions GROUP BY author order by count(author) desc", nativeQuery = true)
List<Object[]> findByAuthorOccurance();
For the query and
List<Object[]> map =submissionRepository.findByAuthorOccurance();
for(Object[] objs : map){
System.out.println((String)objs[0]+" : "+(BigInteger)objs[1]);
}
To get the data.

JPA Typed query set parameter

I have a named parameter in JPA typed query. I am setting a list of value in condition.
I am setting a list of integer, but when JPA converts typed query to corresponding sql query it is adding a to_number function and index of the table is not used.
List<Integer> studentIds=ArrayList<Integer>
//Student id is number in database and indexed.
query = "SELECT T.* FROM STUDENT WHERE STUDENT_ID IN (:studentIds)"
TypedQuery<Object[]> typedQuery = entityManager().createQuery( query, Object[].class);
typedQuery.setParameter("studentIds", studentIds);
The issue is when JPA generates the query it is adding to_number function to convert the list
SELECT * from student t4 where student_id in (?,?,?);
filter("T4"."student_id"=TO_NUMBER(:9) OR "T4"."student_id"=TO_NUMBER(:10) OR
"T4"."student_id"=TO_NUMBER(:11) OR "T4"."PRODUCT_SET_ID"=student_id(:12)
Any thoughts how to make sure JPA does not add a to_number function, so index will be used.
I had to use an array when I was passing values into a '.in' predicate. Try this:
List<Integer> studentIds=ArrayList<Integer>
Integer[] ids = new Integer[studentIds.size()];
ids = studentIds.toArray(ids);
//Student id is number in database and indexed.
query = "SELECT T.* FROM STUDENT WHERE STUDENT_ID IN (:studentIds)"
TypedQuery<Object[]> typedQuery = entityManager().createQuery( query, Object[].class);
typedQuery.setParameter("studentIds", ids);

Using sub queries

I am trying to access a data in a table using a sub query.
The table 1 contains a foreign key to table 2 , which means i can use that key to access the data in table 2.
My problem is after i return the array list from the below shown method , the arraylist is null.
This is what i have done:
LogEntry logBookDates;
List<LogEntry> bookList =new ArrayList();
try{
PreparedStatement getSummaryStmt=con.prepareStatement("SELECT * FROM LOGENTRYTABLE WHERE DIARYCODE =(SELECT Diarycode FROM LOGBOOKTABLE WHERE STUDENTUSERNAME=? OR SUPERVISORUSERNAME=? AND PROJECT_APPROVE_STATUS=?)");
//the above statment is the sub query which i have created, i get the diary code from log book table and then access the log entry table.
getSummaryStmt.setString(1,userName);
getSummaryStmt.setString(2,userName);
getSummaryStmt.setString(3,"Accepted");
ResultSet rs=getSummaryStmt.executeQuery();
while(rs.next())
{
logBookDates=new LogEntry(rs.getString("STUDENTUSERNAME"),rs.getString("SupervisorUsername"),rs.getString("projecttitle"),rs.getString("projectDescription"),rs.getDate("startDate"),rs.getDate("enddate"),rs.getString("project_approve_status"),rs.getString("diarycode"),rs.getString("projectcode"),rs.getInt("Index"),rs.getString("log_Entry"),rs.getDate("logentry_date"),rs.getString("supervisor_comment"),rs.getString("project_progress"));
bookList.add(logBookDates);
}
}catch(Exception e){}
return bookList;
}
I have not used sub queries before and this is the first time am using them.
What seems to be the problem here ?
Thank you for your time.
Edit : Sample data of logbook table
Sample Data of logentry table
Expected output:
I don't have a screen shot of that but what i need is just to iterate through the arraylist which will be returned from the above method.
Here is the problem, the LOGENTRYTABLE table doesn't contain a column with STUDENTUSERNAME, SupervisorUsername, projecttitle, projectDescription, startDate, etc...
rs.getString("STUDENTUSERNAME"), rs.getString("SupervisorUsername"), etc...
probably, you need JOIN query
"SELECT * FROM LOGENTRYTABLE LT
INNER JOIN LOGBOOKTABLE LB ON LT.DIARYCODE=LB.DIARYCODE
WHERE LT.DIARYCODE =
(SELECT DIARYCODE FROM LOGBOOKTABLE
WHERE (STUDENTUSERNAME=? OR SUPERVISORUSERNAME=?)
AND PROJECT_APPROVE_STATUS=?)"

How to run an aggregate function like SUM on two columns in JPA and display their results?

I am new to JPA. So my question should be so simple to some.
Below is the Simple Query in SQL which i would like to convert to JPA. I already have an entity class called TimeEnt.
SELECT
SUM(TimeEntryActualHours) as UnBilledHrs,
SUM (TimeEntryAmount) as UnbilledAmount
FROM TimeEnt WHERE MatterID = 200
The JPA Query Language does support aggregates functions in the SELECT clause like AVG, COUNT, MAX, MIN, SUM and does support multiple select_expressions in the SELECT clause, in which case the result is a List of Object array (Object[]). From the JPA specification:
4.8.1 Result Type of the SELECT Clause
...
The result type of the SELECT
clause is defined by the the result
types of the select_expressions
contained in it. When multiple
select_expressions are used in the
SELECT clause, the result of the query
is of type Object[], and the
elements in this result correspond in
order to the order of their
specification in the SELECT clause
and in type to the result types of
each of the select_expressions.
In other words, the kind of query you mentioned in a comment (and since you didn't provide your entity, I'll base my answer on your example) is supported, no problem. Here is a code sample:
String qlString = "SELECT AVG(x.price), SUM(x.stocks) FROM Magazine x WHERE ...";
Query q = em.createQuery(qlString);
Object[] results = (Object[]) q.getSingleResult();
for (Object object : results) {
System.out.println(object);
}
References
JPA 1.0 Specification
4.8.1 Result Type of the SELECT Clause
4.8.4 Aggregate Functions in the SELECT Clause
Lets think we have entity called Product:
final Query sumQuery = entityManager
.createQuery("SELECT SUM(p.price), SUM(p.sale) FROM Product p WHERE p.item=:ITEM AND ....");
sumQuery.setParameter("ITEM","t1");
final Object result= sumQuery.getSingleResult(); // Return an array Object with 2 elements, 1st is sum(price) and 2nd is sum(sale).
//If you have multiple rows;
final Query sumQuery = entityManager
.createQuery("SELECT SUM(p.price), SUM(p.sale) FROM Product p WHERE p.item in (" + itemlist
+ ") AND ....");
// Return a list of arrays, where each array correspond to 1 item (row) in resultset.
final List<IEniqDBEntity> sumEntityList = sumQuery.getResultList();
Take a look at the EJB Query Language specification.
The idiom is very similiar to standard SQL
EntityManager em = ...
Query q = em.createQuery ("SELECT AVG(x.price) FROM Magazine x");
Number result = (Number) q.getSingleResult ();
Regards,

Categories

Resources