set max results in hibernate not working as per requirement - java

This is my query which is written using HQL. My requirement is as follows.
I've 45 records and I want to fetch 10 records each time. It gives successfully up to 40 records. But from 41-45 records, the query returns empty list.
query1 = session
.createQuery(
"FROM mongo c where "
+ "c.ad='555rs5' and "
+ "c.cId='44444sf' and "
+ "c.langId='59ecc8' and c.date < '"
+ tempDate + "' ORDER BY -date")
.setMaxResults(10);
Anything wrong in my query? Please let me know.
Regards
Naresh Veluri

For Hibernate pagination, next to the setMaxResults() method, you also need the setFirstResult() method. Check out this page.

I guess there must be a problem in your loop.
As per the K.C. answer you have not set setFirstResult() I dont know how your query fetching next records.Read Hibernate Doc - setFirstResult().
Query setFirstResult(int firstResult)
Set the first row to retrieve. If not set, rows will be retrieved beginnning from row 0.
Parameters:
firstResult - a row number, numbered from 0
Try below code hope this will help you to solve your problem.
boolean flag = true;
int firstResult = 0;
int pageSize = 10;
int maxResult = 10;
while(flag) {
query1 = session.createQuery("FROM mongo c where "
+ "c.ad='555rs5' and "
+ "c.cId='44444sf' and "
+ "c.langId='59ecc8' and c.date < '"
+ tempDate + "' ORDER BY -date");
query1.setFirstResult(firstResult);
query1.setMaxResults(maxResult);
List<mongo> = query1.list();
//terminate loop if list is empty or records less than pagesize.
if(list.isEmpty() || list.size() < (maxResult-firstResult)) {
flag = false;
} else {
firstResult = firstResult + pageSize;
maxResult = maxResult + pageSize;
}
}

Related

Select * from SQLite TempTable not working properly

I have this small piece of code, the scope is:
In the outter while: I calculate a "min" number (selected from the tempTable)
In the inner while: I "Select * from (tempTable) where (some conditions)" (im completly sure there is more than 1 row that matches these conditions) and then i update the min in each row selected (whithin other aspects not relevant)
The inner while is conditioned by rs.next() which (as it does in other parts of my code) it should iterate through every row that matches the condition ("Select * from (tempTable) where (some conditions)")
Basically the program should work as: getting a "min" value, then proceed to update each row with equal "min" and "min" = "min" + 1. So in the next iteration of the outter while the "min" should be 1 more.
Instead, what it does is: get "min" value, then update ONLY the first row that matches that min value and goes back to the outter while(which calculates the min again). In the end, the output is rather the same and it kinda works, but I would really appreciate if it worked as I intended to match other aspects of the program.
I think the problem comes from doing a select * from a TEMPtable which for some reason returns only 1 row (i've been investigating but couldnt find other people with the same issue, so i don't really know). As I mentioned, there is other parts of my code where I do the same select * NORMALtable and the ResultSet.Next() works as intended.
while( total_tfgs > 0 ) {
int tfgs_round = 0;
min = prepareStatement.executeQuery("SELECT MIN("+ PROFESORES_COL_TFGS +") FROM TEMP_TABLA_PROFESORES WHERE " + PROFESORES_COL_OBLIGA + " = 'SÍ'").getInt(1);
ResultSet rs = prepareStatement.executeQuery("SELECT * FROM TEMP_TABLA_PROFESORES WHERE " + PROFESORES_COL_TFGS + " = '" + min + "' AND " + PROFESORES_COL_OBLIGA + " = 'SÍ'");
while(rs.next()) {
prepareStatement.executeUpdate("UPDATE TEMP_TABLA_PROFESORES SET PROFESORES_COL_TFGS = PROFESORES_COL_TFGS + 1 WHERE PROFESORES_COL_ID = '" + rs.getInt(1) + "'");
tfgs_round = tfgs_round + 1;
}
total_tfgs = total_tfgs - tfgs_ronda;
}
Here i place code where it works as i want it to work:
Statement statement = con.createStatement();
ResultSet rsA = statement.executeQuery("SELECT * FROM " + TABLA_ALUMNOS);
while(rsA.next()) {
String idA = String.valueOf(rsA.getInt("ALUMNOS_COL_ID"));
String dniA = rsA.getString("ALUMNOS_COL_DNI");
String nombreA = rsA.getString("ALUMNOS_COL_NOMBRE");
String dataA[] = {idA, dniA, nombreA};
DefaultTableModel tblModel = (DefaultTableModel) table_Alumnos.getModel();
tblModel.addRow(dataA);
table_Alumnos.setModel(tblModel);
}
PD: while redacting this i changed some variables to english (in the first code snipet) so it would be more legible(tfgs_round,total_tfgs), so if there is some misspell or something, thats not the problem. Please focus in the ResultSet select * from TEMP_TABLE (which i didnt change)
Thank you in advance for any help you can provide.
I would not call executeUpdate within the loop that is reading the ResultSet. That means you are using the statement for a second query while it is still involved in the first query. I would finish the first query entirely, close the ResultSet and then perform the update separately. If you really need to do an update while reading a ResultSet, I would build a new statement for it.

Column result doesn't as be expected

Here i have query to join two table and merge it into one result by using this query
String query = "SELECT * FROM tb_barang RIGHT JOIN tb_jenis ON tb_barang.kd_jenis = tb_jenis.kd_jenis ";
And here is my table structures for both of tables
Table "tb_barang"
https://i.stack.imgur.com/6OpeC.png
And Table "tb_jenis"
https://i.stack.imgur.com/UhLty.png
I was expecting the output like this
https://i.stack.imgur.com/zhtHx.png
However, when I take column "jenis", java throw exception into it because either out of range or column not found.
Then i check whether the column is exist or not using :
ResultSet resTabel = new mysqlDriver().getKolomBarangList();
ResultSetMetaData metaData = resTabel.getMetaData();
int colCount = metaData.getColumnCount();
if (resTabel.next()) {
for (int i = 1; i <= colCount; i++) {
System.out.println("Col(" + i + ") '" + metaData.getColumnName(i) + "' value:" + resTabel.getString(i));
}
The output:
Col(1) 'kd_barang' value:BAR0000
Col(2) 'nama_barang' value:A
Col(3) 'kd_jenis' value:J_1
Col(4) 'jumlah_barang' value:1
Col(5) 'harga_satuan' value:1
BUILD SUCCESSFUL (total time: 35 seconds)
How to achieve this? Thanks for response
Apparently, i was miss type the method name thanks to #forpas. the getKolomBarangList() refer to field name of table tb_barang and not executing "JOIN" clauses
protected ResultSet getBarangList()throws SQLException, NullPointerException, ClassNotFoundException{
String query = "SELECT * FROM tb_barang RIGHT JOIN tb_jenis ON tb_barang.kd_jenis = tb_jenis.kd_jenis ";
if(resForListBarang == null){
resForListBarang = alwaysDoResultSet(query);
}
return resForListBarang;
}
protected ResultSet getKolomBarangList() throws SQLException, Exception{
String query = "SELECT * FROM tb_barang";
if(getBarangKolom == null){
getBarangKolom = alwaysDoResultSet(query);
}
return getBarangKolom;
}
And the output for getBarangList() was expected as the final result
Col(1) 'kd_barang' value:BAR0000
Col(2) 'nama_barang' value:A
Col(3) 'kd_jenis' value:J_1
Col(4) 'jumlah_barang' value:1
Col(5) 'harga_satuan' value:1
Col(6) 'kd_jenis' value:J_1
Col(7) 'jenis' value:Pakan Hewan
BUILD SUCCESSFUL (total time: 21 seconds)
Thanks to anyone who helping me out :)

Unexpected behaviour of SELECT query after UPDATE

Following is the logic in my java code :
con.setAutoCommit(false);
int starIndex = 0;
List Details = new ArrayList();
while (true) {
isRsEmpty = true;
String my_Query = "select * from x,y,z where"
+ " x.a = y.b"
+ " x.a = z.c"
+ "y.b = z.e"
+ " ORDER BY a ASC"
+ " limit 5"
+ " offset " + starIndex;
preparedStatement = con.prepareStatement(my_Query);
rs = preparedStatement.executeQuery();
while (rs.next()) {
isRsEmpty = false;
//Other processing steps
starIndex++;
Details.add(rs.getInt("id"));
}
if(isRsEmpty){
starIndex = 0;
}
Iterator itr = Details.iterator();
String updateTable = "UPDATE x SET status = ? where i = ? and j = ? and k = ?";
updatePreparedStatement = con.prepareStatement(updateTable);
while (itr.hasNext()) {
updatePreparedStatement.setInt(1, 1);
updatePreparedStatement.setString(2, "zzz");
updatePreparedStatement.setInt(3, 9);
updatePreparedStatement.setInt(4, 10);
updatePreparedStatement.addBatch();
}
updatePreparedStatement.executeBatch();
con.commit();
Details.clear();
}
The Problem :
I have 13 entries in my table which meets the select query.
When I first time run the query my Limit is 5 and Offset is 0 and I get
5 records correctly from the table and the selected 5 records are updated.
After doing the update to the table when the select query runs again it gives me 3 records.This is unexpected since I have more 8 records left in the table.Again the 3 records are updated.
Again when the select query runs it gives me 0 records.
Then again a select query runs which gives me 5 records and updates the 5 records.
I am not able to understand this behaviour. If I run my select query without update then it runs correctly which gives me 5,5,3 records , but with the above logic it gives me 5,3,0,5 records.
What is the problem here ?
Note : In the above program all the variables like PreparedStatement and other are declared correctly.
Thank you
Is there any chance you are missing "and" keyword between your conditions in the select query?
String my_Query = "select * from x,y,z where"
+ " x.a = y.b"
+ " AND x.a = z.c"
+ " AND y.b = z.e"
+ " ORDER BY a ASC"
+ " limit 5"
+ " offset " + starIndex;
I don't know if that would solve the problem but I find it weird that it works like this.

Update multiple tables with JOOQ

the problem here with jooq is that it doesn't support join and updates, moreover updates on multiple tables.
I find a way to transform this query:
String query = "UPDATE knowCRM.customer_did cd ";
query += " LEFT JOIN knowCRM.know_service ks";
query += " ON ks.id = cd.customer_service_id";
query += " LEFT JOIN knowCRM.customer_flags cf";
query += " ON ks.service_owner_id = cf.account_number";
query += " SET cd.is_cli_number= 1, cf.is_cli_number = '0'";
query += " WHERE ks.service_owner_id = " + accountNumber;
query += " AND cd.did_number= " + cliNumber;
into these two:
int count2 = wrapper.getCreate().update(CUSTOMER_DID)
.set(CUSTOMER_DID.IS_CLI_NUMBER, Byte.parseByte("1"))
.where(CUSTOMER_DID.CUSTOMER_SERVICE_ID.equal(
wrapper.getCreate().select(KNOW_SERVICE.ID)
.from(CUSTOMER_FLAGS, KNOW_SERVICE)
.where(KNOW_SERVICE.ID.equal(CUSTOMER_DID.CUSTOMER_SERVICE_ID))
.and(KNOW_SERVICE.SERVICE_OWNER_ID.equal(CUSTOMER_FLAGS.ACCOUNT_NUMBER))
.and(KNOW_SERVICE.SERVICE_OWNER_ID.equal(accountNumber))
.and(CUSTOMER_DID.DID_NUMBER.equal(cliNumber))
))
.execute();
and
int count3 = wrapper.getCreate().update(CUSTOMER_FLAGS)
.set(CUSTOMER_FLAGS.IS_CLI_NUMBER, Byte.parseByte("0"))
.where(CUSTOMER_FLAGS.ACCOUNT_NUMBER.equal(
wrapper.getCreate().select(KNOW_SERVICE.SERVICE_OWNER_ID)
.from(CUSTOMER_DID, KNOW_SERVICE)
.where(KNOW_SERVICE.ID.equal(CUSTOMER_DID.CUSTOMER_SERVICE_ID))
.and(KNOW_SERVICE.SERVICE_OWNER_ID.equal(CUSTOMER_FLAGS.ACCOUNT_NUMBER))
.and(KNOW_SERVICE.SERVICE_OWNER_ID.equal(accountNumber))
.and(CUSTOMER_DID.DID_NUMBER.equal(cliNumber))
))
.execute();
I would like a more clever way to refactor this query with jooq whithout having to split it into two massive queries.
In principle, the JOIN operations are specified on an org.jooq.Table. There's a pending feature request to add "join convenience methods" also to UPDATE, just as they exist also on SELECT: #3266
Your original query can be written as such in jOOQ:
CustomerDid cd = CUSTOMER_DID.as("cd");
KnowService ks = KNOW_SERVICE.as("ks");
CustomerFlags cf = CUSTOMER_FLAGS.as("cf");
ctx.update(cd.leftJoin(kd)
.on(ks.ID.eq(cd.CUSTOMER_SERVICE_ID))
.leftJoin(cf)
.on(ks.SERVICE_OWNER_ID.eq(cf.ACCOUNT_NUMBER)))
.set(cd.IS_CLI_NUMBER, 1)
.set(cf.IS_CLI_NUMBER, "0")
.where(ks.SERVICE_OWNER_ID.eq(accountNumber))
.and(cd.DID_NUMBER.eq(cliNumber))
.execute();

Hibernate Criteria - get count of subselect

I would like to count the number of events that fulfill a certain condition. If the row count is less than a million I would like to get the actual number. If it is more than a million I do not need to know the exact number and it is ok to return the count as 1 million.
I thought about this query
select count(*) from (select id from events where x=10 limit 1000000) a
How can it be done Detached Criteria / sub criteria?
Is there a better way of doing it other than the above sql? I'm using postgresql 9.3
That query won't perform better than a regular count, so try this instead:
long count = ((Number)
session.createCriteria(Event.class)
.setProjection(Projections.rowCount())
.add(Restrictions.eq("x", 10))
.uniqueResult()).longValue();
long countLimit = Math.min(count, 1000000);
As I understood
You have to count some recode if it is >1000000 it should show 1 Million +
else exact count.
For this you cat try this query
String t;
t = (String) session.createQuery(
"select case when count(*)>1000000 "
+ "then '1Million +' "
+ "else count(*) "
+ "end "
+ "from events").uniqueResult();
session.getTransaction().commit();
System.out.println("size is " + t);
Use CASE [ WHEN {test_conditional} THEN {match_result} ]* ELSE {miss_result} END
https://docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html/ch11.html#d5e3280

Categories

Resources