I have a function which reads a List of Notifications Object. Now I have to read the Notifications object in batches of 100(suppose) and update it.
public boolean addBSInfoToTemp(List<ParentNotification> pNotify)
throws DaoException, BatchUpdateException {
int cnt = 0;
final String query = "insert into Temp values ?,?,?,'Y','N',?,?,?,?";
while (!pNotify.isEmpty()) {
try {
pst = getConnection().prepareStatement(query);
for (ParentNotification pn : pNotify) {
cnt++;
pst.setInt(1, pn.getUserId());
pst.setString(2, pn.getEmail());
pst.setString(3, pn.getNotificationType());
Date createdDate = (Date) pn.getCreatedDate();
pst.setDate(4, createdDate);
pst.setString(5, pn.getCreatedBy());
Date icsesCreatedDate = (Date) pn.getIcsesCreatedDate();
pst.setDate(6, icsesCreatedDate);
pst.setString(7, pn.getMiscellaneous());
pst.addBatch();
if(cnt==batchCount){
break;
}
}
int[] batch = pst.executeBatch();
if (batch.length != 0) {
flag = true;
}
} catch (BatchUpdateException b) {
flag = false;
} catch (SQLException sqlx) {
flag = false;
} finally {
close(pst, null);
}
}
return flag;
}
What I am trying to do is read the List with batchCount = 100 then update and go back to 101 record and then update another 100 records untill the List is empty.
You have this:
while (!pNotify.isEmpty()) {
but I don't see that you ever remove objects from the list, so you have infinite loop. I would just make the outside loop to loop through all of the elements like this:
for (int i=0; i<=pNotify.size(); i++){
// and inside check if it is devisible by batch length
if(i % batchCount == 0){
break;
}
}
Related
this is a online exam system. if the answer is correct marks increment by 1 it is work correctly at the same question second time select wrong answer i i need decrement the value
int marks;
String cor;
public void answerCheck()
{
String answerAnswer="";
if(r1.isSelected())
{
answerAnswer = r1.getText();
}
else if(r2.isSelected())
{
answerAnswer = r2.getText();
}
else if(r3.isSelected())
{
answerAnswer = r3.getText();
}
else if(r4.isSelected())
{
answerAnswer = r4.getText();
}
if(answerAnswer.equals(cor))
{
marks = marks + 1;
String Marks = String.valueOf(marks);
txtc.setText(Marks);
}
else if(!answerAnswer.equals(cor))
{
marks = marks - 1;
String Marks = String.valueOf(marks);
txtc.setText(Marks);
}
else
{
marks =0;
}
}
i am loading all data from the database correct answer also i am loading
Database Load
public void Connection()
{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost/onlineex","root","");
String query = "select * from questions";
pst = con.prepareStatement(query);
rs = pst.executeQuery();
while(rs.next())
{
txtqu.setText(rs.getString("id"));
txtques.setText(rs.getString("question"));
r1.setText(rs.getString(3));
r2.setText(rs.getString(4));
r3.setText(rs.getString(5));
r4.setText(rs.getString(6));
cor = rs.getString(7);
}
}
i have a button call next
try
{
if(rs.previous())
{
txtques.setText(rs.getString("question"));
r1.setText(rs.getString(3));
r2.setText(rs.getString(4));
r3.setText(rs.getString(5));
r4.setText(rs.getString(6));
cor=rs.getString(7);
}
else
{
JOptionPane.showMessageDialog(this, "This is first record of student");
}
answerCheck();
}
i have button call previous
if(rs.next())
{
txtques.setText(rs.getString("question"));
r1.setText(rs.getString(3));
r2.setText(rs.getString(4));
r3.setText(rs.getString(5));
r4.setText(rs.getString(6));
cor=rs.getString(7);
}
else
{
JOptionPane.showMessageDialog(this, "This is first record of student");
}
answerCheck();
Firstly there is a Logical error in last else which will never execute because either answer is correct or wrong there is no third condition.
String cor;
public void answerCheck()
{
String answerAnswer="";
if(r1.isSelected())
{
answerAnswer = r1.getText();
}
else if(r2.isSelected())
{
answerAnswer = r2.getText();
}
else if(r3.isSelected())
{
answerAnswer = r3.getText();
}
else if(r4.isSelected())
{
answerAnswer = r4.getText();
}
if(answerAnswer.equals(cor))
{
marks = marks + 1;
String Marks = String.valueOf(marks);
txtc.setText(Marks);
}
else if(!answerAnswer.equals(cor) || ((r1.isSelected() ||
r2.isSelected() || r3.isSelected() || r4.isSelected()))
{
marks = marks - 1;
String Marks = String.valueOf(marks);
txtc.setText(Marks);
}
}
Does jdbcTemplate.batchUpdate execute multiple single insert statements OR 1 multi value list insert on the database server?
I know that it sends the complete query payload at once to the server but am not sure how the execution takes place.
Can someone please explain/help?
From question:
Does jdbcTemplate.batchUpdate execute multiple single insert statements OR 1 multi value list insert on the database server?
From comment:
I was curious about int[] org.springframework.jdbc.core.JdbcTemplate.batchUpdate(String sql, List<Object[]> batchArgs, int[] argTypes)
TL;DR: It executes 1 multi-valued list.
Spring Framework is open-source, so it's easy to look at the source code and see that is actually does.
batchUpdate(String sql, List<Object[]> batchArgs, final int[] argTypes)
#Override
public int[] batchUpdate(String sql, List<Object[]> batchArgs, final int[] argTypes) throws DataAccessException {
if (batchArgs.isEmpty()) {
return new int[0];
}
return batchUpdate(
sql,
new BatchPreparedStatementSetter() {
#Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
Object[] values = batchArgs.get(i);
int colIndex = 0;
for (Object value : values) {
colIndex++;
if (value instanceof SqlParameterValue) {
SqlParameterValue paramValue = (SqlParameterValue) value;
StatementCreatorUtils.setParameterValue(ps, colIndex, paramValue, paramValue.getValue());
}
else {
int colType;
if (argTypes.length < colIndex) {
colType = SqlTypeValue.TYPE_UNKNOWN;
}
else {
colType = argTypes[colIndex - 1];
}
StatementCreatorUtils.setParameterValue(ps, colIndex, colType, value);
}
}
}
#Override
public int getBatchSize() {
return batchArgs.size();
}
});
}
As can be seen, it calls the following method.
batchUpdate(String sql, final BatchPreparedStatementSetter pss)
#Override
public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss) throws DataAccessException {
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL batch update [" + sql + "]");
}
int[] result = execute(sql, (PreparedStatementCallback<int[]>) ps -> {
try {
int batchSize = pss.getBatchSize();
InterruptibleBatchPreparedStatementSetter ipss =
(pss instanceof InterruptibleBatchPreparedStatementSetter ?
(InterruptibleBatchPreparedStatementSetter) pss : null);
if (JdbcUtils.supportsBatchUpdates(ps.getConnection())) {
for (int i = 0; i < batchSize; i++) {
pss.setValues(ps, i);
if (ipss != null && ipss.isBatchExhausted(i)) {
break;
}
ps.addBatch();
}
return ps.executeBatch();
}
else {
List<Integer> rowsAffected = new ArrayList<>();
for (int i = 0; i < batchSize; i++) {
pss.setValues(ps, i);
if (ipss != null && ipss.isBatchExhausted(i)) {
break;
}
rowsAffected.add(ps.executeUpdate());
}
int[] rowsAffectedArray = new int[rowsAffected.size()];
for (int i = 0; i < rowsAffectedArray.length; i++) {
rowsAffectedArray[i] = rowsAffected.get(i);
}
return rowsAffectedArray;
}
}
finally {
if (pss instanceof ParameterDisposer) {
((ParameterDisposer) pss).cleanupParameters();
}
}
});
Assert.state(result != null, "No result array");
return result;
}
As can be seen, it creates a single PreparedStatement, enters a loop calling addBatch(), and finally calls executeBatch().
So, the short answer is: 1 multi-valued list.
The full answer is that it likely sends one SQL statement and a multi-valued list to the database server, however it is entirely up to the JDBC driver how it actually implements batching, mostly limited by what the communication protocol supports, so the only way to know for sure is to trace the communication with the server.
I am having my array overwritten by the last Object and Am not sure why as a System.out.println() on the same Location prints all the items correctly. I am attempting to update a table containing Student scores with their ranks but all students get the last item on the array.
public static void updateSubjectRank(String subject, String extype, int academicyear, int semester, int level) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Criteria cr = session.createCriteria(EduResults.class);
cr.add(Restrictions.eq("subject", subject));
cr.add(Restrictions.eq("extype", extype));
cr.add(Restrictions.eq("acedemicyear", academicyear));
cr.add(Restrictions.eq("semester", semester));
cr.add(Restrictions.eq("level", level));
ScrollableResults items = cr.scroll();
int count = 0;
double[] scores = getSubjectScores(subject, extype, academicyear, semester, level);//this gets all the scores in a double array
int[] ranks = Rank.getRank(scores);//this gives me the ranks of the scores above
while (items.next()) {
EduResults res = (EduResults) items.get(0);
for (int i : ranks) {
res.setSubjectRank(i + 1);//this updates the database with the last item in the array
System.out.println(i+1);///this prints the ranks properly
session.saveOrUpdate(res);
}
if (++count % 100 == 0) {
session.flush();
session.clear();
}
}
tx.commit();
} catch (Exception asd) {
log.debug(asd.getMessage());
if (tx != null) {
tx.rollback();
}
} finally {
session.close();
}
}
I have seen similar questions but this looks strange as the System out prints them correctly. I'm I missing something here?
res.setSubjectRank(i + 1); is not this line updating the subject rank repeatedly in the loop? What do you expect this to do? In the first iteration it will update it and will keep updating till the last iteration and the last iteration will have the last item from the ranks array.
I finally found a way around this. I am going to post the Answer for the sake of anyone that might be experiencing the same problem. Since the Students having the same score will have the same rank, you can iterate for each score and Update the Rank. Like this:
public static void updateSubjectRank(String subject, String extype, int academicyear, int semester, int level) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
double[] scores = getSubjectScores(subject, extype, academicyear, semester, level);
int[] ranks = Rank.getRank(scores);
for (double d : scores) {
Criteria cr = session.createCriteria(EduResults.class);
int rank = Rank.getRank(Rank.getRank(scores), Rank.getArrayIndex(scores, d)) + 1;
cr.add(Restrictions.eq("subject", subject));
cr.add(Restrictions.eq("extype", extype));
cr.add(Restrictions.eq("acedemicyear", academicyear));
cr.add(Restrictions.eq("semester", semester));
cr.add(Restrictions.eq("level", level));
cr.add(Restrictions.eq("scorePcnt", d));
ScrollableResults items = cr.scroll();
int count = 0;
while (items.next()) {
EduResults res = (EduResults) items.get(0);
res.setSubjectRank(rank);
System.out.println(rank);
session.saveOrUpdate(res);
if (++count % 100 == 0) {
session.flush();
session.clear();
}
}
}
tx.commit();
} catch (Exception asd) {
log.debug(asd.getMessage());
if (tx != null) {
tx.rollback();
}
} finally {
session.close();
}
}
The problem is that when I enter some character in JComboBox then it just autoselected, again I enter other text then it replace the first character, so I am not able to type multiple character in JComboBox(my JComboBox is editable)...
pleasw help.
private void combo1KeyReleased(java.awt.event.KeyEvent evt)
{
if((evt.getKeyChar() >= '0' && evt.getKeyChar() <= '9')||(evt.getKeyChar() >= 'a' && evt.getKeyChar() <= 'z')||(evt.getKeyChar() >= 'A' && evt.getKeyChar() <= 'Z')||evt.getKeyCode() == KeyEvent.VK_BACK_SPACE)
{
try
{
Connection con=null;
ResultSet rs;
con=LoginConnection.getConnection();
String srch="";
if(con!=null)
{
srch=(String)combo1.getEditor().getItem();
System.out.println("value to search:"+srch);
String s="select name from supplier where name like '%"+srch+"%' order by name";
PreparedStatement pst=con.prepareStatement(s,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
rs=pst.executeQuery();
int itemCount = combo1.getItemCount();
System.out.println("no of value="+itemCount);
for(int i=0;i<itemCount;i++){ //removing items
combo1.removeItemAt(0);
}
if(!rs.next())
{
System.out.println("----------------------No Data Found");
}
else
{
rs.beforeFirst();
while(rs.next())
{
combo1.addItem(rs.getString(1)); // addind item
System.out.println("while value is:"+rs.getString(1));
}
}
combo1.getEditor().setItem(srch);// adding item in field which i have fetched using getItem method
combo1.showPopup();
}
}
catch(Exception e)
{
System.out.println("ex:"+e);
}
}
}
I'm getting an Exhausted resultset form the following code.
I've tried a few different things now and can't find a solution,
if I don't call the songs method it works, but the songs method works when it's called, can't get my head around it, hoping I'm missing something simple.
public void refreshList() {
rset = po.getProduct();
if (plist.size() > 0) {
for (int i = plist.size() - 1; i >= 0; i--) {
plist.remove(i);
}
}
try {
while (rset.next()) {
songs(rset.getString(1));
CD c = new CD(alist);
Product p = new Product(rset.getString(1),
rset.getString(2),
rset.getString(3),
rset.getDouble(4),
rset.getDouble(5),
rset.getInt(6),
rset.getString(7),
rset.getString(8),
rset.getString(9),
rset.getDouble(10), c);
plist.add(p);
}
} catch (Exception ex) {
System.out.println(ex);
}
}
public void songs(String ID)
{
rset = po.getSongs();
alist = new ArrayList<Song>();
try {
while (rset.next()){
Song s = new Song(rset.getString(1),
rset.getString(2),
rset.getString(3));
slist.add(s);
}
}
catch (Exception ea) {
System.out.println(ea);
}
for(int i = 0; i < slist.size(); i++)
{
if(slist.get(i).getSong_id().equals(ID))
{
alist.add(slist.get(i));
}
}
}
Inside refreshList you have while (rset.next()) loop, on each iteration of it you have songs(rset.getString(1));, which itself has while(rset.next(). This leads to result set exhaustion, because when you return from songs() you try to take some more data from the current position of result set, while in songs() you got out of while (rset.next()) loop, i.e. retrieved all its rows. Consider refactoring your code to avoid nested loops based on result set.