I have a TextArea Object, and I have SQL query running, I have the GUI unusable until the SQL query is finished, I would like to get the GUI refreshed meanwhile.
Your SQL query is running on the Event Dispatch Thread (EDT) which is preventing the GUI from updating itself until the long running task is finished.
You need to run the query on a separate Thread.
An easy way to do this is to use a Swing Worker.
Read the section from the Swing tutorial on Concurrency for more information on the EDT and for examples of using a SwingWorker.
private String printCommandCalled(String argument) throws SQLException {
String finalResult = "";
url = url.substring(0, 15 + port.length() + adress.length()).concat(currentDatabaseName + "?useSSL=false");
try {
connection = (Connection) DriverManager.getConnection(url, userName, password);
statement = (Statement) connection.createStatement();
resultSet = (ResultSet) statement.executeQuery("SELECT * FROM " + argument + ";");
} catch (SQLException e) {
}
int i = resultSet.getMetaData().getColumnCount();
//this is the try block that takes too long resulting the unresponsiveness of the gui
try {
while (resultSet.next()) {
for (int j = 1; j <= i; j++)
finalResult += resultSet.getObject(j) + " ";
finalResult += '\n';
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int k = 1; k <= i; k++)
finalResult += resultSet.getMetaData().getColumnName(k) + " ("
+ resultSet.getMetaData().getColumnTypeName(k) + ") ";
finalResult += '\n';
//this output is a string that will be shown in the JTextArea object
return finalResult;
}
Related
I wrote this function to easily populate my database(mySQL) :
public boolean addItems(Connection con) throws SQLException {
try {
con.setAutoCommit(false);
String[] brands = { "Honda", "BMW", "Mercedes Benz" };
String[] optional = { "acciaio", "alluminio", "carbonio", "titanio" };
Statement statement = con.createStatement();
for (int i = 0; i < brands.length; i++) {
for (int j = 0; j < optional.length; j++) {
statement.executeUpdate("INSERT INTO chassis (idUnit, brand, material, availableItems) VALUES (1, '" + brands[i] + "', '" + optional[j] + "', 20)");
statement = Condb.replaceStatement(statement);
ResultSet rs = statement.executeQuery("SELECT * FROM chassis WHERE brand = '" + brands[i] + "' AND material = '" + optional[j] + "'");
while (rs.next()) {
statement = Condb.replaceStatement(statement);
statement.executeUpdate("INSERT INTO product_code (unitName, productCode, brand, optional) VALUES ('chassis', " + rs.getInt("productCode") + ", '" + brands[i] + "', '" + optional[j] + "')");
con.commit();
}
}
}
return true;
} catch (Exception exception) {
exception.printStackTrace();
con.rollback();
return false;
}
}
But it adds one record in 'chassis' table (first update), then it doesn't enter in the while loop ('productCode' field is an auto increment field, so I need to take it from chassis table in order to add a record in 'product_code' table).
After this, it increase the j variable, executes the update in the chassis table, enters in the while loop and at the update (in the loop) it throws a SQLException
Operation not allowed after ResultSet closed
But it never executes the rollback. So I have records in my chassis table, but product_code table is empty.
This is my replaceStatement function :
public static Statement replaceStatement(Statement stmt) {
try {
stmt.close();
Statement statement = Condb.initializeDatabase().createStatement();
return statement;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Anyone can help me solve this issue?
You can't commit and then request a rollback. For a connection that you use with plain JDBC either make a single commit in the end or trigger a rollback if some statements fails.
So con.commit(); should be placed just before return true
Otherwise you can handle manualy multiple transactions inside your loops following this answer https://stackoverflow.com/a/47482143/7237884
Alright so I need help in reviewing my codes because I'm kinda still new in programming (currently in my second year of Diploma in Computer Science). I got this error as in the title GC Overhead Limit Exceeded when I tried running my code below.
A brief explanation of this code, I'm trying to read data from a CSV File and then transfer it to a database. FYI, there are actually 10 tables/CSV files that I need to read, but on this I'll show this one table Tickets because the error only occurred when I tried to read that table/file. The other tables have hundreds of rows/data only while the table Tickets have 735,504 of rows/data. Furthermore, I've succeeded in reading 450,028 of data after 6 hours of running the code before the error occurred.
What can I do to fix this error? What can be modified to improve my code? I really appreciate it if you guys can help me :)
public class Demo2 {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/database";
String username = "root";
String password = "password";
try {
//Connect to the database
Connection connection = DriverManager.getConnection(url, username, password);
//Test on one table only
String tableName = "Tickets";
System.out.println("Connecting to TABLE " +tableName +"...");
readCSVFile(tableName, connection);
System.out.println();
System.out.println("THE END");
connection.close();//close connection to the database
}
catch (SQLException e) {
System.out.println("ERROR at main(): SQLException!!");
e.printStackTrace();
}
}
static int countNewRow = 0;
static int countUpdatedRow = 0;
//Method to read the CSV File
static void readCSVFile(String tableName, Connection conn) {
//Read CSV File
try {
String path = tableName +".csv";
BufferedReader br = new BufferedReader(new FileReader(path));
br.readLine();//skip the first line
String inData;
//Read The Remaining Line
while((inData=br.readLine()) != null)
{
String[] rowData = inData.split(",");
ArrayList <String> rowDataList = new ArrayList<String>();
for (int i=0; i<rowData.length; i++)
rowDataList.add(rowData[i]);
//To combine String that starts and ends with "
for(int i=0; i<rowDataList.size(); i++) {
if (rowDataList.get(i).charAt(0) == '"') {
String string1 = rowDataList.get(i).substring(1, rowDataList.get(i).length());
String string2 = rowDataList.get(i+1).substring(0, rowDataList.get(i+1).length()-1);
String combined = string1 +"," +string2;
rowDataList.set(i, combined);
rowDataList.remove(i+1);
break;
}
}
//Remove the RM
for(int i=0; i<rowDataList.size(); i++) {
if (rowDataList.get(i).startsWith("RM")) {
String string = rowDataList.get(i).substring(2);
rowDataList.set(i, string);
}
}
//This is just to keep track of the data that has been read
System.out.println("[" +rowDataList.get(0) +"]");
//Transfer the data to the database
insertToDatabase(conn, tableName, rowDataList);
}
System.out.println("New Row Added : " +countNewRow);
System.out.println("Updated Row : " +countUpdatedRow);
System.out.println("== Process Completed ==");
br.close();
}
catch (FileNotFoundException e) {
System.out.println("ERROR at readCSVFile(): FileNotFoundException!!");
e.printStackTrace();
}
catch (IOException e) {
System.out.println("ERROR at readCSVFile(): IOException!!");
e.printStackTrace();
}
catch (SQLException e) {
System.out.println("ERROR at readCSVFile(): SQLException!!");
e.printStackTrace();
}
catch (ParseException e) {
System.out.println("ERROR at readCSVFile(): ParseException!!");
e.printStackTrace();
}
}
static void insertToDatabase(Connection connection, String tableName, ArrayList <String> rowDataList) throws SQLException, ParseException {
String tableIdName = tableName;
if (tableIdName.charAt(tableIdName.length()-1) == 's')
tableIdName = tableIdName.substring(0, tableIdName.length()-1);
//To read row
String rowID = rowDataList.get(0);
String selectSQL = "SELECT * FROM " +tableName +" "
+"WHERE " +tableIdName +"_ID = " +rowID;
Statement statement = connection.createStatement();
ResultSet result = statement.executeQuery(selectSQL);
boolean value = result.next();
//INSERT # UPDATE row
if (value == true) { //Update Row if the data is already existed
updateStatementt(tableName, connection, rowDataList);
countUpdatedRow++;
}
else { //Insert New Row
insertStatementt(tableName, connection, rowDataList);
countNewRow++;
}
}
//Method to insert data to the database
static void insertStatementt(String tableType, Connection conn, ArrayList <String> rowDataList) throws SQLException, ParseException {
//Generate Question Mark
String generateQuestionMark = null;
if(rowDataList.size() == 1)
generateQuestionMark = "?";
else
generateQuestionMark = "?, ";
for(int i=1; i<rowDataList.size(); i++) {
if(i!=rowDataList.size()-1)
generateQuestionMark += "?, ";
else
generateQuestionMark += "?";
}
//Insert sql
String sql = "INSERT INTO " +tableType +" VALUES (" +generateQuestionMark +")";
PreparedStatement insertStatement = conn.prepareStatement(sql);
//Insert data
//There are other 'if' and 'else if' statements here for other tables
else if (tableType.equals("Tickets")) {
int ticketID = Integer.parseInt(rowDataList.get(0));
int movieId = Integer.parseInt(rowDataList.get(1));
int theaterId = Integer.parseInt(rowDataList.get(2));
String[] date = rowDataList.get(3).split("/");
String dateString = date[2] +"-" +date[1] +"-" +date[0];
Date showDate = Date.valueOf(dateString);
int showTimeId = Integer.parseInt(rowDataList.get(4));
int cptId = Integer.parseInt(rowDataList.get(5));
int pcId = Integer.parseInt(rowDataList.get(6));
float amountPaid = Float.parseFloat(rowDataList.get(7));
int year = Integer.parseInt(rowDataList.get(8));
String month = rowDataList.get(9);
insertStatement.setInt(1, ticketID);
insertStatement.setInt(2, movieId);
insertStatement.setInt(3, theaterId);
insertStatement.setDate(4, showDate);
insertStatement.setInt(5, showTimeId);
insertStatement.setInt(6, cptId);
insertStatement.setInt(7, pcId);
insertStatement.setFloat(8, amountPaid);
insertStatement.setInt(9, year);
insertStatement.setString(10, month);
}
insertStatement.executeUpdate();
insertStatement.close();
}
//Method to update the data from the database
static void updateStatementt(String tableType, Connection conn, ArrayList <String> rowDataList) throws SQLException {
Statement statement = conn.createStatement();
String sql = "UPDATE " +tableType;
//There are other 'if' and 'else if' statements here for other tables
else if (tableType.equals("Tickets")) {
String[] date = rowDataList.get(3).split("/");
String dateString = date[2] +"-" +date[1] +"-" +date[0];
sql += " SET movie_id = " +rowDataList.get(1) +","
+ " theater_id = " +rowDataList.get(2) +","
+ " showdate = \"" +dateString +"\","
+ " showtime_id = " +rowDataList.get(4) +","
+ " costperticket_id = " +rowDataList.get(5) +","
+ " personcategory_id = " +rowDataList.get(6) +","
+ " amount_paid = " +rowDataList.get(7) +","
+ " year = " +rowDataList.get(8) +","
+ " month = \"" +rowDataList.get(9) +"\""
+ " WHERE ticket_id = " +rowDataList.get(0);
}
statement.executeUpdate(sql);
}
}
For short, read a single line and do whatever you want to do with it. You don't have enough memory for all 700k lines.
You should add statement.close() for the update Statement.
If you really want to read all this data into the Java heap, increase the heap size using, for example, the -Xmx command-line switch. Because of the way textual data is encoded in the JVM, you'll probably need much more heap that the total data size would suggest.
In addition, there might be some places in your code where you can take the strain off the JVM's memory management system. For example, concatenating strings using "+" can generate a lot of temporary data, which will increase the load on the garbage collector. Assembling strings using a StringBuilder might be a simple, less resource-hungry, alternative.
I have code, where I have single quote or APOSTROPHE in my search
I have database which is having test table and in name column of value is "my'test"
When running
SELECT * from test WHERE name = 'my''test';
this works fine
If I use the same in a Java program I am not getting any error or any result
But If I give the name with only single quote then it works
SELECT * from test WHERE name = 'my'test';
Could you please help me out to understand.
Java code is
Connection con = null;
PreparedStatement prSt = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.
getConnection("jdbc:oracle:thin:#localhost:1521:orcl"
,"user","pwd");
String query = "SELECT * from "
+ "WHERE name = ? ";
prSt = con.prepareStatement(query);
String value = "my'mobile";
char content[] = new char[value.length()];
value.getChars(0, value.length(), content, 0);
StringBuffer result = new StringBuffer(content.length + 50);
for (int i = 0; i < content.length; i++) {
if (content[i] == '\'')
{
result.append("\'");
result.append("\'");
}
else
{
result.append(content[i]);
}
}
prSt.setObject(1, result.toString());
int count = prSt.executeUpdate();
System.out.println("===============> "+count);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally{
try{
if(prSt != null) prSt.close();
if(con != null) con.close();
} catch(Exception ex){}
}
You don't have to escape anything for the parameter of a PreparedStatement
Just use:
prSt = con.prepareStatement(query);
prSt.setString("my'mobile");
Additionally: if you are using a SELECT statement to retrieve data, you need to use executeQuery() not executeUpdate()
ResultSet rs = prst.executeQuery();
while (rs.next())
{
// process the result here
}
You might want to go through the JDBC tutorial before you continue with your project: http://docs.oracle.com/javase/tutorial/jdbc/index.html
I have this code:
buy.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent actionEvent)
{
int r;
r = table.getSelectedRow();
String num = (String) table.getValueAt(r, 0);//numele jucariei
//String cop = (String) table.getValueAt(r, 3);//nr de bucati
try
{
pq = stmt.executeQuery("SELECT *" + "FROM buyid_view");
xv = stmt.executeQuery("SELECT toyid, copies " + "FROM alldatas_view" + "WHERE toyname ='"+num+"'");
int buyid = pq.getInt("buyid");
int toyid = xv.getInt("toyid");
int copies = xv.getInt("copies");
copies = copies-1;
CallableStatement cstmt = con.prepareCall("INSERT INTO buy (buyid, toyid)" + "VALUES (?,?)");
cstmt.setInt("buyid", buyid);
cstmt.setInt("toyid", toyid);
ResultSet rs = cstmt.executeQuery();
JOptionPane.showMessageDialog(null, "You brought a toy.");
for(int i = 0; i < table.getRowCount(); i++)
for(int j = 0; j < table.getColumnCount(); j++)
table.setValueAt("", i, j);
try
{
rs = stmt.executeQuery("UPDATE toys set copies "+ copies +"WHERE toyid= '"+toyid+"'");
}
catch (SQLException e)
{
JOptionPane.showMessageDialog(null, e.getMessage());
}
int i = 0;
try
{
rs = stmt.executeQuery("SELECT *"+
"FROM availablebooks_view");
}
catch (SQLException e)
{
e.printStackTrace();
}
finally
{
try {
if(rs.next())
{
table.setValueAt(rs.getString(1), i, 0);
table.setValueAt(rs.getString(2), i, 1);
table.setValueAt(rs.getString(3), i, 2);
i++;
while(rs.next())
{
table.setValueAt(rs.getString(1), i, 0);
table.setValueAt(rs.getString(2), i, 1);
table.setValueAt(rs.getString(3), i, 2);
i++;
}
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(null, e.getMessage());
}
}
}
catch (SQLException e)
{
if(e.getMessage().contains("You have to pay!"))
warning(frame, "You didn't pay all your products");
else
warning(frame, e.getMessage());
}
}
});
When I compile my program I don't have any error but when I run it and I click on the buy button it gives me an error saying "ORA-00933: SQL command not properly ended".
When building SQL statements from strings you must ensure there are spaces where spaces are needed.
rs = stmt.executeQuery("SELECT *"+
"FROM availablebooks_view");
The statement you are sending is
SELECT *FROM availablebooks_view
which is invalid syntax. You have this problem in several places in your code.
However, you have a larger issue which results from building your SQL statements piecemeal. This leaves you open to SQL Injection and you should rewrite your code to use prepared statements and parameters instead.
There are multiple errors in your code
First one is
rs = stmt.executeQuery("SELECT *"+
"FROM availablebooks_view");
There is no space between * and FROM, this will actually creates a syntax error
Second one is
rs = stmt.executeQuery("UPDATE toys set copies "+ copies +"WHERE toyid= '"+toyid+"'");
There is no = after set copies, this will also create error.
Third one is
CallableStatement cstmt = con.prepareCall("INSERT INTO buy (buyid, toyid)" + "VALUES (?,?)");
Give space before VALUES
I'm working on java JDK7 and Microsoft Access 2007.Basically I want to get the minimum value from the all the columns of row1. But the following code doesn't work.
import java.io.*;
import java.util.*;
import java.net.*;
import java.sql.*;
public class server
{
public void check()
{
int min = 100, row = 0, index, i = 2;
try {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection cn = DriverManager.getConnection("jdbc:odbc:DSN2");
Statement st = cn.createStatement();
ResultSet rs = st.executeQuery("select *from Table1");
rs.next();
System.out.println(rs.getInt(1) + "\t" + rs.getInt(2) + "\t" + rs.getInt(3) + "\t" + rs.getInt(4) + "\t" + rs.getInt(5) + "\t" + rs.getInt(6));
for (i = 2; i < 7; i++)
{
System.out.println("hello");
if (rs.getInt(i) < min) {
index = i;
min = rs.getInt(i);
}
}
} catch (Exception e) {
e.getMessage();
}
switch (i) {
case 2:
ioConnect();
break;
case 3:
break;
case 4:
ioConnect();
break;
case 5:
ioConnect();
break;
case 6:
ioConnect();
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void ioConnect() {
try {
ServerSocket ss = new ServerSocket(2000);
Socket so = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("enter the message");
String str = br.readLine();
PrintStream ps = new PrintStream(so.getOutputStream());
ps.println(str);
} catch (Exception e) {
e.getMessage();
}
}
}
class serverm {
public static void main(String s[]) {
servern obj = new servern();
obj.check();
}
}
So here I get the output the first row each column values that's fine, but when the control enters the for loop the println statement prints the hello only once and the cursor blinks. This indicates the the program has not ended correctly.
Your first problem is that you don't know what your problem is...
To solve this problem, and get to solve the real issue, instead of this
catch(Exception e)
{
e.getMessage();
}
Use
catch(Exception e)
{
e.printStackTrace();
}
And please paste the full stack trace this produces...
EDIT
As OP stated in a comment:
there is no data found exception thrown
This means that there is no data to be read. Which is a known case for MS Access:
This typically occurs when you try to read the value of a column multiple times.
So you should only read every value once! To fix the imediate issue, comment the System.out.println() line here
...
rs.next();
// comment this:
// System.out.println(rs.getInt(1) + "\t" + rs.getInt(2) + "\t" + rs.getInt(3) + "\t" + rs.getInt(4) + "\t" + rs.getInt(5) + "\t" + rs.getInt(6));
for (i = 2; i < 7; i++)
...
And be careful, as you call getInt() for the same index two times in the loop, which has to be corrected:
for (i = 2; i < 7; i++)
{
System.out.println("hello");
if (rs.getInt(i) < min) { // getInt()
index = i;
min = rs.getInt(i); // second getInt() call for same index --- throws exception
}
}
Correct:
for (i = 2; i < 7; i++)
{
System.out.println("hello");
int value=rs.getInt(i); // getInt() call, put into local variable
if (value < min) {
index = i;
min = value; //just use local variable - OK
}
}
It is a small mistake that you have done. Irrespective of whether the result has record or not, you are calling rs.getInt(1)... . Use classical JDBC way of testing whether result set has records or not.
while(rs.next()){
rs.getInt(1);
}