ResultSet object reaches the end after one iteration - java

I'm trying to read all records in a table from a database, and do some processing using those data. Following is the code that I use.
package differences;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
public class ConformancePercentageChecking {
private final String dbDriver = "com.mysql.jdbc.Driver";
private Connection connection = null;
private final String serverName = "localhost";
private final String mydatabase = "google";
private final String username = "root";//kh hoseinpur
private final String password = "123";
private final String extrainfo = "?useUnicode=true&characterEncoding=UTF-8";
int numberOfInsertedIDs = 0;
public void findConformances() {
try {
try {
Class.forName(dbDriver);//a call to forname("X") causes the class named X to be initialized
String url = "jdbc:mysql://" + serverName + "/" + mydatabase + extrainfo;
if (connection == null) {
connection = (Connection) DriverManager.getConnection(url, username, password);
}
} catch (ClassNotFoundException | SQLException e) {
JOptionPane.showMessageDialog(null, "database");
}
String query1, query2, query3, query4, query5, query6, testSuite, id;
PreparedStatement statement1, statement2, statement3, statement4, statement5, statement6;
query1 = "drop table PresConformance;";
query2 = "drop table PostConformance;";
statement1 = connection.prepareStatement(query1);
statement2 = connection.prepareStatement(query2);
statement1.executeUpdate();
statement2.executeUpdate();
query1 = "CREATE TABLE PresConformance(testSuite Text, conformance numeric(10), depthDifference numeric(10),pathLength numeric(10));";
query2 = "CREATE TABLE PostConformance(testSuite Text, conformance numeric(10), depthDifference numeric(10),pathLength numeric(10));";
query3 = "SELECT * FROM presDifference;";
query4 = "SELECT * FROM presdifference;";
query5 = "insert into PresConformance values(?,?,?,?);";
query6 = "insert into PostConformance values(?,?,?,?);";
statement1 = connection.prepareStatement(query1);
statement2 = connection.prepareStatement(query2);
statement3 = connection.prepareStatement(query3);
statement4 = connection.prepareStatement(query4);
statement5 = connection.prepareStatement(query5);
statement6 = connection.prepareStatement(query6);
Map<String, String> map = new HashMap<>();
statement1.executeUpdate();
statement2.executeUpdate();
ResultSet r1, r2, r3, r4;
r1 = statement3.executeQuery();
System.out.println("***1");
r2 = statement4.executeQuery();
System.out.println("***2");
int idCount = 0, depthDifference = 0, totalNumberOfExecutions = 0, testSuitesCounts = 0, difference = 0, pathLength = 0;
float conformancePercentage = 0, sumOfconformancePercentage = 0;
r3 = r1;
r4 = r2;
while (r1.next()) {
testSuitesCounts = 0;
sumOfconformancePercentage = 0;
testSuite = r1.getString("testSuite");
id = null;
id = map.get(testSuite);
if (id == null) {
idCount++;
map.put(Integer.toString(idCount), testSuite);
r3.absolute(r1.getRow());
r3.previous();
while (r3.next()) {
if (testSuite.equals(r3.getString("testSuite"))) {
System.out.println(testSuite + " equal");
totalNumberOfExecutions = r3.getInt("totalNumberOfExecutions");
difference = r3.getInt("difference");
conformancePercentage = (1 - ((float) difference / totalNumberOfExecutions)) * 100;
if (testSuitesCounts == 0) {
String[] testSuite1, testSuite2, testSuite3;
testSuite1 = testSuite.split("_");
testSuite2 = testSuite1[0].split("/");
testSuite3 = testSuite1[1].split("/");
depthDifference = Math.abs(testSuite2.length - 1) - testSuite3.length;
pathLength = (testSuite2.length - 1) + testSuite3.length;
}
testSuitesCounts++;
sumOfconformancePercentage += conformancePercentage;
}
}
statement5.setString(1, testSuite);
statement5.setFloat(2, (sumOfconformancePercentage / testSuitesCounts));
statement5.setInt(3, depthDifference);
statement5.setInt(4, pathLength);
statement5.executeUpdate();
}
System.out.println(r1.getRow());
}
System.out.println("Pres Finished*****************************************");
idCount = 0;
map = new HashMap<>();
while (r2.next()) {
testSuitesCounts = 0;
sumOfconformancePercentage = 0;
testSuite = r2.getString("testSuite");
id = null;
id = map.get(testSuite);
if (id == null) {
idCount++;
map.put(Integer.toString(idCount), testSuite);
r4.absolute(r2.getRow());
r4.previous();
while (r4.next()) {
if (testSuite.equals(r4.getString("testSuite"))) {
System.out.println(testSuite + " equal");
totalNumberOfExecutions = r4.getInt("totalNumberOfExecutions");
difference = r4.getInt("difference");
conformancePercentage = (1 - ((float) difference / totalNumberOfExecutions)) * 100;
if (testSuitesCounts == 0) {
String[] testSuite1, testSuite2, testSuite3;
testSuite1 = testSuite.split("_");
testSuite2 = testSuite1[0].split("/");
testSuite3 = testSuite1[1].split("/");
depthDifference = Math.abs(testSuite2.length - 1) - testSuite3.length;
pathLength = (testSuite2.length - 1) + testSuite3.length;
}
testSuitesCounts++;
sumOfconformancePercentage += conformancePercentage;
}
}
statement6.setString(1, testSuite);
statement6.setFloat(2, (sumOfconformancePercentage / testSuitesCounts));
statement6.setInt(3, depthDifference);
statement6.setInt(4, pathLength);
statement6.executeUpdate();
}
}
System.out.println("Post Finished*****************************************");
System.out.println("Finished Inserting to DB");
} catch (SQLException ex) {
Logger.getLogger(DifferencesPresPost.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
The problem, is that for both ResultSet objects r1 and r3, which contain tables' records, it just iterates once, and then reaches the end of the ResultSet objects.
I tried to count number of records in both ResultSet objects before each while loop, and it correctly prints the number of recoreds, but when it enters in these while loops, it works for only first row of each ResultSet objects.
Can any body help me to find out the result of this problem?

I believe by default your resultsets are TYPE_FORWARD_ONLY. You need to specify TYPE_SCROLL_INSENSITIVE when preparing your prepared statements. Hope this helps.

Related

To import data into mysql

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Formatter;
public class JtoCModified {
private static final String COMMA_DELIMITER = ",";
private static final String DB_DRIVER = "com.mysql.jdbc.Driver";
private static final String DB_CONNECTION="jdbc:mysql://localhost:3306/test2";
private static final String DB_USER = "root";
private static final String DB_PASSWORD = "root";
private static int RECORD_COUNT =24;
static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";
static final String DATE_FORMAT = "yyyy-MM-dd";
static final String TIME_FORMAT = "HH:mm:ss";
private static final int ADD_MINUTES = 2;
static final String FromDate = "2016-01-01 00:00:00";
#SuppressWarnings("unused")
public static void main(String[] args) throws Exception {
List<String> records = new ArrayList<String>();
StringBuffer record = new StringBuffer();
DateFormat d_f = new SimpleDateFormat(DATE_FORMAT);
DateFormat tf = new SimpleDateFormat(TIME_FORMAT);
Calendar cal = Calendar.getInstance();
cal.setTime(d_f.parse(FromDate));
record.append("\t");
for (int i = 1; i <= RECORD_COUNT; i++) {
if (i % 100000 == 0) {
records = new ArrayList<String>(RECORD_COUNT);
}
for (int j = 0; j < 2730; j++) {
int OPV = 230 + j % 15; // 230 - 244 by 1
String String = Integer.toString(OPV);
String str = Integer.toString(OPV);
record.append("OPV");
double IKW = 1.3 + j % 17 * 0.1; // 1.3 - 2.9 by 0.1
String aString = Double.toString(IKW);
String IKW2 = String.valueOf(IKW);
record.append("IKW");
double OKW = 0.01 + j % 49 * 0.01; // 0.01 - 0.49 by 0.01
String bString = Double.toString(IKW);
String OKW2 = String.valueOf(OKW);
record.append("OKW");
double OPI = 0.05 + j % 105 * 0.01; // 0.05 - 1.09 by 0.01
String cString = Double.toString(OPI);
String OPI2 = String.valueOf(OPI);
record.append("OPI");
double IPI = 0.00 + j % 8 * 0.01;
String dString = Double.toString(IPI);
String IPI2 = String.valueOf(IPI);
record.append("IPI");
int NA1 = 000;
String eString = Integer.toString(NA1);
String NA12 = Integer.toString(NA1);
record.append("NA1");
int BVV = 104 + j % 13;
String fString = Integer.toString(BVV);
String BVV2 = Integer.toString(BVV);
record.append("BVV");
double BVI = 1.3 + j % 15 * 0.8;
String gString = Double.toString(BVI);
String BVI2 = String.valueOf(BVI);
record.append("BVI");
int NA2 = 000;
String hString = Integer.toString(NA2);
String NA22 = Integer.toString(NA2);
record.append("NA2");
int NA3 = 000;
String iString = Integer.toString(NA3);
String NA32 = Integer.toString(NA3);
record.append("NA3");
int IPV = 241 + j % 1;
String jString = Integer.toString(IPV);
String IPV2 = Integer.toString(IPV);
record.append("IPV");
int _IF = 50;
String kString = Integer.toString(_IF);
String _IF2 = Integer.toString(_IF);
record.append("_IF");
int _OF = 50;
String lString = Integer.toString(_OF);
String _OF2 = Integer.toString(_OF);
record.append("_OF");
int NA4 = 000;
String mString = Integer.toString(NA4);
String NA42 = Integer.toString(NA4);
record.append("NA4");
int SERIAL = 12345;
String oString = Integer.toString(SERIAL);
String SERIAL2 = Integer.toString(SERIAL);
record.append("SERIAL");
int NA5 = 000;
String nString = Integer.toString(NA4);
String NA52 = Integer.toString(NA5);
record.append("NA5");
int NA6 = 000;
String qString = Integer.toString(NA6);
String NA62 = Integer.toString(NA6);
record.append("NA6");
int STATUS = 000 + j % 001;
String rString = Integer.toString(STATUS);
String STATUS2 = Integer.toString(STATUS);
record.append("STATUS");
int PVV=000;
String sString = Integer.toString(PVV);
String PVV2 = Integer.toString(NA2);
record.append("PVV");
double PVI=00.0;
String tString = Double.toString(PVI);
String PVI2 = String.valueOf(OPI);
record.append("PVI");
double PKW=00.0;
String uString = Double.toString(PKW);
String PKW2 = String.valueOf(PKW);
record.append("PKW");
double PKWH=00.0;
String vString = Double.toString(PKWH);
String PKWH2 = String.valueOf(PKWH);
record.append("PKWH");
record.append((d_f.format(cal.getTime()))+", "+tf.format(cal.getTime()));
int Device_id=101;
addToBuffer(record, Device_id);
record.append("\n");
cal.add(Calendar.MINUTE, ADD_MINUTES);
records.add(record.toString());
record.delete(0, record.length());
addToBuffer(record,OPV);
addToBuffer(record,IKW);
addToBuffer(record,OKW);
addToBuffer(record,OPI);
addToBuffer(record,IPI);
addToBuffer(record,NA1);
addToBuffer(record,BVV);
addToBuffer(record,BVI);
addToBuffer(record,NA2);
addToBuffer(record,NA3);
addToBuffer(record,IPV);
addToBuffer(record,_IF);
addToBuffer(record,_OF);
addToBuffer(record,NA4);
addToBuffer(record,SERIAL);
addToBuffer(record,NA5);
addToBuffer(record,NA6);
addToBuffer(record,NA6);
addToBuffer(record,PVV);
addToBuffer(record,PVI);
addToBuffer(record,PKW);
addToBuffer(record,PKWH);
record.delete(0, record.length());
record.append(OKW);
record.append(OPI);
record.append(IPI);
record.append(NA1);
record.append(BVV);
record.append(BVI);
record.append(NA2);
record.append(NA3);
record.append(IPV);
record.append(_IF);
record.append(_OF);
record.append(NA4);
record.append(SERIAL);
record.append(NA5);
record.append(NA6);
record.append(STATUS);
record.append(PVV);
record.append(PVI);
record.append(PKW);
record.append(PKWH);
record.append(STATUS);
record.append((d_f.format(cal.getTime()))+", "+tf.format(cal.getTime()));
record.append("\t\t");
record.append(COMMA_DELIMITER);
// int Device_id=101;
addToBuffer(record, Device_id);
record.append("\n");
cal.add(Calendar.MINUTE, ADD_MINUTES);
records.add(record.toString());
String insertTableSQL = "INSERT INTO DBUSER"
+ "(OPV, IKW, OKW ,OPI, IPI,NA1, BVV, BVI,NA2, NA3,IPV, _IF, _OF,NA4 , SERIAL ,NA5, NA6, STATUS ,PVI ,PKW , PKWH) "
+ "VALUES" + "("+ OPV + IKW + OKW + OPI + IPI + NA1 + BVV + BVI + NA2 + NA3 + IPV + _IF + _OF + NA4 + SERIAL + NA5 + NA6 + STATUS+ PVI + PKW + PKWH +")";
// record.append("\t\t");
record.append(COMMA_DELIMITER);
try {
insertRecordIntoDbUserTable();
Connection dbConnection = null;
Statement statement = null;
dbConnection = getDBConnection();
statement = dbConnection.createStatement();
System.out.println(insertTableSQL);
// execute insert SQL stetement
statement.executeUpdate(insertTableSQL);
System.out.println(insertTableSQL);
System.out.println("Record is inserted into DbUser table!");
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
}
}
}
}
private static void addToBuffer(StringBuffer buffer, Object data) {
buffer.append(data);
buffer.append(", ");
}
private static void insertRecordIntoDbUserTable()
{
}
private static Connection getDBConnection() {
Connection dbConnection = null;
try {
Class.forName(DB_DRIVER);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
try {
dbConnection = DriverManager.getConnection(
DB_CONNECTION, DB_USER,DB_PASSWORD);
return dbConnection;
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return dbConnection;
}
}
I want to export data from java to mysql db but i am not getting any data, initially i want to print the data in console after that i want to add into a database table .I have done jdbc connectivity.But still its not fetching any data please suggest me something.I am getting data in console but not in format what should i do to make the console data in format and to export data into db.
There is a problem with the SQL statement you create here:
String insertTableSQL = "INSERT INTO DBUSER"
+ "(OPV, IKW, OKW ,OPI, IPI,NA1, BVV, BVI,NA2, NA3,IPV, _IF, _OF,NA4 , SERIAL ,NA5, NA6, STATUS ,PVI ,PKW , PKWH) "
+ "VALUES" + "("+ OPV + IKW + OKW + OPI + IPI + NA1 + BVV + BVI + NA2 + NA3 + IPV + _IF + _OF + NA4 + SERIAL + NA5 + NA6 + STATUS+ PVI + PKW + PKWH +")";
Print out the insertTableSQL string to see what it actually contains.
Also, I think there should be an error message printed by this:
System.out.println(e.getMessage());
Show it to us.
UPDATE
INSERT INTO DBUSER(OPV, IKW, OKW ,OPI, IPI,NA1, BVV, BVI,NA2,
NA3,IPV, _IF, _OF,NA4 , SERIAL ,NA5, NA6, STATUS ,PVI ,PKW , PKWH)
VALUES(2341.70000000000000020.050.090.0401084.50024150500123450000.00.00.0)
As I suspected, the problem is that your string concatenation has resulted in an SQL statement with one long meaningless "value". It is invalid SQL.
The solutions:
Put commas between the values in your concatenation.
Use a PreparedStatement instead of a Statement with ? placeholders, and then use setXxxx to set the query arguments.

Populating jtree from oracle db

package com.view.custom;
import com.mysql.jdbc.DatabaseMetaData;
import com.mysql.jdbc.ResultSetMetaData;
import com.util.DBConnection;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
public class ReadData {
public static String getTableData(Connection con) {
String col_attr1 = "";
try {
ArrayList tablename = new ArrayList();
Statement stt = con.createStatement();
String database = "Source Tables";
ResultSet rs = null;
DatabaseMetaData meta = (DatabaseMetaData) con.getMetaData();
rs = meta.getTables(null, null, null, new String[] { "TABLE" });
while (rs.next()) {
String ab = rs.getString("TABLE_NAME");
System.out.println(ab);
tablename.add(ab);
}
for (Object tablename1 : tablename) {
String sql = "Select * from " + tablename1.toString();
String table_name = tablename1.toString();
System.out.println("Table name " + table_name);
ResultSet rs1 = stt.executeQuery(sql);
ResultSetMetaData metadata = (ResultSetMetaData) rs1.getMetaData();
int cou = metadata.getColumnCount();
String col_attr = "";
String profile1 = "";
for (int j = 1; j <= cou; j++) {
String ab = metadata.getColumnName(j);
for (int c = j; c <= cou; c++) {
String val = "";
while (rs1.next()) {
val += rs1.getString(c) + "$";
}
rs1.beforeFirst();
if (val.length() > 1)
val = val.substring(0, val.lastIndexOf("$"));
profile1 += ab + "#" + val + "|";
break;
}
}
profile1 = profile1.substring(0, profile1.lastIndexOf("|"));
col_attr1 += table_name + "#" + profile1 + "\n";
}
} catch (Exception e) {
e.printStackTrace();
}
return col_attr1;
}
public static JTree getTree(String str, String rootName) {
str = str.substring(0, str.lastIndexOf("\n"));
String args[] = str.split("\n");
DefaultMutableTreeNode dt = new DefaultMutableTreeNode(rootName);
for (String arg : args) {
String[] aa = arg.split("#"); // table name
String bb[] = aa[1].split("\\|");
System.out.println("table lenght: " + aa.length);
DefaultMutableTreeNode dm = new DefaultMutableTreeNode(aa[0]);
System.out.println("table : " + aa[0]);
dt.add(dm);
for (String bb1 : bb) {
String[] dd = bb1.split("#"); // col value
DefaultMutableTreeNode dm1 = new DefaultMutableTreeNode(dd[0]);
dm.add(dm1);
if (dd.length > 1) {
String dd1[] = dd[1].split("\\$");
for (String dd11 : dd1) {
DefaultMutableTreeNode dm2 = new DefaultMutableTreeNode(
dd11);
dm1.add(dm2);
}
}
}
}
return new JTree(dt);
}
}
It is not fetching the tree.

java return data to java client

i have java client send to server (jetty-xmlrpc) query and receive data from server inside hashmap. sometime data is more big(e.g. 3645888 rows), when this data send to java client i have error ( java heap space ). how can i send data by 2 times for example ? or give me way to fix it
this is server function to get data and send it to client
public HashMap getFlickValues(String query,String query2){
System.out.println("Query is : "+query);
System.out.println("Query2 is: "+query2);
Connection c = null;
Connection c2 = null;
Statement st = null;
Statement st2 = null;
HashMap<String, Object[]> result = new HashMap<String, Object[]>();
ArrayList<Double> vaArrL = new ArrayList<Double>();
ArrayList<Double> vbArrL = new ArrayList<Double>();
ArrayList<Double> vcArrL = new ArrayList<Double>();
try {
Class.forName("org.postgresql.Driver");
String conString = "jdbc:postgresql://" + host + ":" + port + "/" + DBName +
"?user=" + user + "&pass=" + pass;
String conString1 = "jdbc:postgresql://" + host + ":" + port2 + "/" + DBName2 +
"?user=" + user + "&pass=" + pass;
//String conString1 = "jdbc:postgresql://127.0.0.1:5431/merkezdbram " +
// "?user=" + user + "&pass=" + pass;
/*c = DriverManager.getConnection(conString);
st = c.createStatement();
ResultSet rs = st.executeQuery(query);
while (rs.next()){
vaArrL.add(rs.getDouble("va"));
vbArrL.add(rs.getDouble("vb"));
vcArrL.add(rs.getDouble("vc"));
}*/
c = DriverManager.getConnection(conString);
//c.setAutoCommit(false);
c2 = DriverManager.getConnection(conString1);
//c2.setAutoCommit(false);
st = c.createStatement();
//st.setFetchSize(1000);
st2 = c2.createStatement();
//st2.setFetchSize(1000);
List<ResultSet> resultSets = new ArrayList<>();
resultSets.add(st.executeQuery(query));
resultSets.add(st2.executeQuery(query2));
ResultSets rs = new ResultSets(resultSets);
int count = 0;
int ResultSetSize = rs.getFetchSize();
System.out.println("ResultSetSize is "+ResultSetSize);
while (rs.next()){
//count++;
//if ( count == 2200000) { break;}
vaArrL.add(rs.getDoubleVa("va"));
vbArrL.add(rs.getDoubleVb("vb"));
vcArrL.add(rs.getDoubleVc("vc"));
}
int sz = vaArrL.size();
result.put("va", vaArrL.toArray(new Object[sz]));
result.put("vb", vbArrL.toArray(new Object[sz]));
result.put("vc", vcArrL.toArray(new Object[sz]));
//rs.close();
st.close();
c.close();
} catch ( Exception e ) {
System.out.println(e);
e.printStackTrace();
}
System.out.println("Flicker vaArrL.size = "+vaArrL.size());
return result;
}
and ResultSets class is :
class ResultSets {
private java.util.List<java.sql.ResultSet> resultSets;
private java.sql.ResultSet current;
public ResultSets(java.util.List<java.sql.ResultSet> resultSets) {
this.resultSets = new java.util.ArrayList<>(resultSets);
current = resultSets.remove(0);
}
public boolean next() throws SQLException {
if (current.next()) {
return true;
}else if (!resultSets.isEmpty()) {
current = resultSets.remove(0);
return next();
}
return false;
}
public Double getDoubleVa(String va) throws SQLException{
return current.getDouble("va");
}
public Double getDoubleVb(String vb) throws SQLException{
return current.getDouble("vb");
}
public Double getDoubleVc(String vc) throws SQLException{
return current.getDouble("vc");
}
}
i want way to return data to client without (java heap space) ?
i make -Xmx1024m for VM argument , but same problrm
i want solution in my code
thanks

How to resolve Lock wait timeout exceeded exception in SQL?

I am FTP'ing a file from a remote server and inserting/updating it in my db. I am using MySql db. But I am seeing java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction exception and also the row is being inserted into my db at the same time. How can I resolve this issue?.
The error from the log is below:
SEVERE: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1078)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4187)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4119)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2815)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2322)
at com.sun.gjc.spi.jdbc40.PreparedStatementWrapper40.executeQuery(PreparedStatementWrapper40.java:642)
at ft.util.KeyGenerator.generateKey(KeyGenerator.java:92)
at ft.util.KeyGenerator.generateKey(KeyGenerator.java:44)
at processes.FTPInbound.connectAndGetListOfFiles(FTPInbound.java:242)
at com.washpost.main.Main.main(Main.java:24)
at lockbox.beans.LOCKBOX_MessageBean.onMessage(LOCKBOX_MessageBean.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
The error points to rset = stmt.executeQuery (); in the below code:
package com.washpost.ft.util;
import java.io.*;
import java.util.*;
import java.sql.*;
import java.util.logging.*;
public class KeyGenerator {
private static HashMap keyTbl = new HashMap();
private static Vector keyLock = new Vector();
private final static long MAX_KEY_COUNT = 999999999;
private final static int KEY_INC_COUNTER = 1;
public KeyGenerator() {
}
public static long generateKey(String sequenceName)
throws Exception {
long keyValue;
synchronized(keyLock) {
String key = sequenceName;
Key data = (Key) keyTbl.get(key);
if(data == null || (data.currentValue == data.maxValue)) {
// Need to put retry logic
keyValue = generateKey(sequenceName,KEY_INC_COUNTER);
if(keyValue == -1) {
throw new Exception ("SequenceName not in SEQUENCE_GENERATOR table :" + sequenceName );
}
data = new Key(keyValue,keyValue,keyValue + KEY_INC_COUNTER);
keyTbl.put(key,data);
}
keyValue = data.currentValue;
data.currentValue++;
return keyValue;
}
}
public static synchronized long generateKey(String sequenceName,int count)
throws Exception {
PreparedStatement stmt=null;
ResultSet rset=null;
Connection db_conn = null;
StringBuffer sql = new StringBuffer();
long key=-1;
long maxKeyCount;
String sqlSeqNum="";
try {
// db_conn = Utility.getConnection("PASDataSource");
db_conn = Util.getConnection("ftpds");
sql.append("SELECT SEQ_NUM ");
sql.append("FROM SEQUENCE_GENERATOR ");
//SJ 2009.02.11, commented and added line below
//sql.append("WHERE sequence_name = ? ");
sql.append("WHERE SEQUENCE_NAME = ? for update");
System.out.println(sql + "::" + sequenceName);
stmt = db_conn.prepareStatement(sql.toString());
stmt.clearParameters();
stmt.setString(1,sequenceName);
rset = stmt.executeQuery ();
// Iterate through the result set
while(rset.next()) {
key = rset.getInt(1);
// Update the key
}
rset.close();
stmt.close();
stmt = null;
rset = null;
if(key != -1) {
if((key + count) > MAX_KEY_COUNT) {
// reset key count
// key = 1;
sqlSeqNum = "";
}
else
sqlSeqNum = " seq_num + ";
sql = new StringBuffer();
sql.append("UPDATE SEQUENCE_GENERATOR SET SEQ_NUM = " + sqlSeqNum + count );
sql.append(" WHERE SEQUENCE_NAME = ? ");
sql.append(" AND SEQ_NUM = ? ");
stmt = db_conn.prepareStatement(sql.toString());
stmt.clearParameters();
stmt.setString(1,sequenceName);
stmt.setLong(2,key);
if(stmt.executeUpdate() != 1) {
System.out.println(
":Not able to generate a new UNIQUE key for sequence :" + sequenceName);
throw new Exception("Not able to generate a new UNIQUE key for sequence :" + sequenceName );
}
return key;
}
return -1;
}
catch (Exception e) {
System.out.println(e.getMessage());
throw e;
}
finally {
Util.release(db_conn, stmt, rset);
System.out.println("Closing Connection in KeyGenerator(generateKey).");
}}
}
The best thing would be control this using the auto increment of mysql.
But if you have to control the keys in your application, you can use this classes...
SequenceBlockCache
SequenceBlock

Make this program more efficient?

just curious if anyone has any idea for making this program more simple. It reads records from a database into an ArrayList and allows the user to search for records by state. It processes a database of 1 million records in aprox 16000ms.
import java.sql.*;
import java.util.*;
public class ShowEmployeeDB
{
public static void main(String args[])
{
ArrayList <String> Recs = new ArrayList <String>();
String driverName = "sun.jdbc.odbc.JdbcOdbcDriver";
String connectionURL = "jdbc:odbc:CitizensDB";
Connection con = null;
Statement stmt = null;
String sqlStatement = "SELECT * FROM Citizens";
ResultSet rs = null;
int r = 0;
Scanner scan = new Scanner(System.in);
String search = null;
long starttime = System.currentTimeMillis();
try
{
Class.forName(driverName).newInstance();
con = DriverManager.getConnection(connectionURL);
stmt = con.createStatement();
rs = stmt.executeQuery(sqlStatement);
String ID = null;
String Age = null;
String State = null;
String Gender = null;
String Status = null;
String record = null;
while (rs.next())
{
for (int k = 1; k <= 1; ++k)
{
ID = rs.getString(k) + " ";
for (int j = 2; j <= 2; ++j)
Age = rs.getString(j) + " ";
for (int i = 3; i <= 3; ++i)
State = rs.getString(i).toUpperCase() + " ";
for (int h = 4; h <= 4; ++h)
Gender = rs.getString(h) + " ";
for (int g = 5; g <= 5; ++g)
Status = rs.getString(g) + " ";
}//for
record = ID + Age + State + Gender + Status;
Recs.add(record);
++r;
}//while
rs.close();
stmt.close();
con.close();
} catch (Exception ex) { ex.printStackTrace(); }
String endtime = System.currentTimeMillis() - starttime + "ms";
System.out.println(endtime);
System.out.print("Enter A Search State: ");
search = scan.nextLine().toUpperCase();
Iterator<String> iter = Recs.iterator();
while(iter.hasNext())
{
String s = iter.next();
if (s.contains(search))
{
System.out.println(s);
}
}//while
} // main
} // ShowEmployeeBD
Any advice would be greatly appreciated. Thank you in advance!
If search is not often, I would suggest to take the search string input before running the query, so that search results are directly from the DB. I this case you do not have to reiterate all 1 million records.
Perform searching directly on DB rather than fetching all the records and searching through java code.
Also if search is on multiple column, then prepare a meta data in DB at a single place on the basis of IDs, and the meta data can further be used for fetching the required results that match the query.
Separate your logic from the technical stuff. In such a convolut it is difficult to run unit tests or any optimizations.
Why do you need for loops, when only asking one value.
Use StringBuilder instead of String concatenation.
Use either try-with or put your close statements in a finally clause.
Don't initialize variables you don't need (r).
Use for each statements.
Query the database, not the result set.
Tune your database.
If you are only searching for a state, filter only those, so build an object and compare the state instead of a string contains.
Compare the state before storing strings in the list.
Tune your list because it constantly grows with 1Mio records.
Use a hashset instead of an arraylist.
Develop against interfaces.
A better program might look like following:
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class ShowEmployeeDB {
private static final String DRIVERNAME = "sun.jdbc.odbc.JdbcOdbcDriver";
private static final String CONNECTIONURL = "jdbc:odbc:CitizensDB";
private static final String SELECT_CITIZENS = "SELECT * FROM Citizens";
static {
try {
DriverManager.registerDriver((Driver) Class.forName(DRIVERNAME).newInstance());
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
public static void main(final String args[]) {
System.out.print("Enter A Search State: ");
searchRecords();
}
private static void searchRecords() {
try(Scanner scan = new Scanner(System.in);) {
final String state = scan.nextLine();
final long starttime = System.currentTimeMillis();
final Set<Record> records = searchRecordsByState(state);
System.out.println(System.currentTimeMillis() - starttime + "ms");
for(final Record r : records) {
System.out.println(r);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static Set<Record> searchRecordsByState(final String stateToFilter) {
final Set<Record> records = new HashSet<>();
try(Connection con = DriverManager.getConnection(CONNECTIONURL);
PreparedStatement stmt = con.prepareStatement(SELECT_CITIZENS);
ResultSet rs = stmt.executeQuery(); ) {
while(rs.next()) {
final String state = rs.getString(3);
if(state.equalsIgnoreCase(stateToFilter)) {
final Record r = new Record(rs.getString(1), rs.getString(2), state, rs.getString(4), rs.getString(5));
records.add(r);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return records;
}
}
class Record {
String id, age, state, gender, status;
public Record(String id, String age, String state, String gender, String status) {
this.id = id;
this.age = age;
this.state = state;
this.gender = gender;
this.status = status;
}
public String getState() {
return state;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(id).append(' ')
.append(age).append(' ')
.append(state).append(' ')
.append(gender).append(' ')
.append(status);
return sb.toString();
}
}
This is untested, because I don't have a database with a million entries by hand.
But the best would be to query the database and catch only those entries you need. So use the WHERE-clause in your statement.

Categories

Resources