I have a JavaFX application which uses an embedded database to store all data. Establishing a connection and inserting data works just fine besides the column 'id' auto incrementing by 100 instead of 1. I've read(Wrong auto increment in embedded Derby/ Java DB) that I have to shut down the database properly by using following code in my main class:
#Override
public void stop() {
try {
DriverManager.getConnection("jdbc:derby:"+"db"+";shutdown=true");
}
catch (SQLException sqlException){
sqlException.printStackTrace();
System.out.println("Database shutted down...");
}
}
However it's still incrementing by 100 and I'm not sure why.
My code for establishing a connection and doing inserts:
try {
Connection connection = DriverManager.getConnection("jdbc:derby:db");
connection.setAutoCommit(true);
System.out.println("Connection established");
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO orders(order_name, order_date, price) VALUES (?, ?, ?)");
preparedStatement.setString(1, "TestOrder");
preparedStatement.setDate(2, Date.valueOf(LocalDate.now()));
preparedStatement.setDouble(3, 1.1);
preparedStatement.execute();
preparedStatement.close();
connection.close();
} catch (SQLException throwables) {
System.out.println("Unable to establish connection");
throwables.printStackTrace();
}
And my SQL statement to create the table
DROP TABLE orders;
CREATE TABLE orders(
order_number INTEGER PRIMARY KEY NOT NULL GENERATED ALWAYS AS IDENTITY(START WITH 1, INCREMENT BY 1),
order_name VARCHAR(100),
order_date DATE,
price DECIMAL(4, 2));
Related
I am using SQL Server 2018 and JDK 8.0 along with NetBeans. While connecting to the SQL Server, I am getting a SQL Exception as shown in the img
enter image description here
I am using the following code:
try{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
//Connection establishment
Connection con=DriverManager.getConnection("jdbc:sqlserver//DESKTOP-CU5U75J\\SQLSERVER1;","","");
//Statement Object
Statement st=con.createStatement();
//For DML use executeUpdate method of Statement Class
st.executeUpdate("insert into Employee (Employee_Id, Employee_Name) values ("+Integer.parseInt(idTF.getText())+","+nameTF.getText()+")");
//Commit Statement
con.commit();
JOptionPane.showMessageDialog(this, "Message", "The Data is Entered", JOptionPane.INFORMATION_MESSAGE);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Employe.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(Employe.class.getName()).log(Level.SEVERE, null, ex);
}
You have missed colon ':' in your jdbc url,
Connection con=DriverManager.getConnection("jdbc:sqlserver://DESKTOP-CU5U75J\\SQLSERVER1;integratedSecurity=true","","");
It was jdbc:sqlserver//DESKTOP-CU5U75J\\SQLSERVER1; which was supposed to be jdbc:sqlserver://DESKTOP-CU5U75J\\SQLSERVER1;
Also, I suggest you to use PreparedStatement to insert your records.
String sql="insert into Employee (Employee_Id, Employee_Name) values (?,?)";
PreparedStatement stmt=con.prepareStatement(sql);
stmt.setInt(1, Integer.parseInt(idTF.getText()));
stmt.setString(2, nameTF.getText());
stmt.executeUpdate();
I have an error of
java.sql.SQLException: The prepared statement has been finalized
which happens when I call the same preparedStatement a second time. I am calling it in a method.
Here is the database Java class (the relevant piece)
//create the charge table. (ps is PreparedStatement)
try{
statement.executeUpdate("CREATE TABLE charge(username TEXT NOT NULL, date DATETIME DEFAULT CURRENT_TIMESTAMP, charge REAL, PRIMARY KEY(username, date));");
} catch (SQLException ex) {
System.out.println("charge table creation failed. exception" + ex);
}
Method that creates a charge:
public void createCharge(String username, double amount){
try {
System.out.println(username + amount);
ps = connection.prepareStatement("INSERT INTO charge VALUES(?, ?, ?);");
ps.setString(1, username);
ps.setDate(2, DateConvert.toSQLDate(Date.valueOf(LocalDate.MIN)));
ps.setDouble(3, amount);
ps.executeUpdate();
ps.clearParameters();
System.out.println("Complete");
} catch (SQLException ex) {
Logger.getLogger(MontsRentalDatabase.class.getName()).log(Level.SEVERE, null, ex);
}
}
This is in the class where the charge is created:
public void createCharge(String username, double amount){
try {
System.out.println(username + amount);
ps = connection.prepareStatement("INSERT INTO charge VALUES(?, ?, ?);");
ps.setString(1, username);
ps.setDate(2, DateConvert.toSQLDate(Date.valueOf(LocalDate.MIN)));
ps.setDouble(3, amount);
ps.executeUpdate(); //Line 170
ps.clearParameters();
System.out.println("Complete");
} catch (SQLException ex) {
Logger.getLogger(MontsRentalDatabase.class.getName()).log(Level.SEVERE, null, ex);
}
}
The class that converts a normal date to sqldate:
public class DateConvert {
public static java.sql.Date toSQLDate(java.util.Date date){
return new java.sql.Date(date.getTime());
}
public static java.util.Date toJavaDate(java.sql.Date date){
return new java.util.Date(date.getTime());
}
}
The error is in line 170 of create charge, which is when ps.executeUpdate runs. It runs successful the first time, fails on the second.
Log:
450100.0
Complete
450150.0
SEVERE: null
java.sql.SQLException: The prepared statement has been finalized
at org.sqlite.core.NativeDB.throwex(NativeDB.java:429)
at org.sqlite.core.NativeDB.reset(Native Method)
at org.sqlite.core.DB.executeUpdate(DB.java:878)
at org.sqlite.jdbc3.JDBC3PreparedStatement.executeUpdate(JDBC3PreparedStatement.java:99)
at server.RentalDatabase.createCharge(RentalDatabase.java:170)
Thanks for any help,
J
I believe that this is a bug in version 3.14.2.1 of the SQLite JDBC driver.
It seems to me that you're getting a unique constraint violation exception, but the SQLite JDBC driver is tripping over itself attempting to report this exception and some other exception is getting thrown instead.
I was able to reproduce your exception using sqlite-jdbc version 3.14.2.1 if I tried to insert the same data multiple times, e.g. by re-running your code. I downgraded the SQLite JDBC driver to 3.8.11.2 and I got the following exception after running your code:
java.sql.SQLException: [SQLITE_CONSTRAINT] Abort due to constraint violation (UNIQUE constraint failed: charge.username, charge.date)
at org.sqlite.core.DB.newSQLException(DB.java:890)
at org.sqlite.core.DB.newSQLException(DB.java:901)
at org.sqlite.core.DB.execute(DB.java:810)
at org.sqlite.core.DB.executeUpdate(DB.java:847)
at org.sqlite.jdbc3.JDBC3PreparedStatement.executeUpdate(JDBC3PreparedStatement.java:86)
at com.example.MontsRentalDatabase.createCharge(MontsRentalDatabase.java:40)
at com.example.Main.main(Main.java:17)
Of course, when re-running the program, the data I'm trying to insert is in the table already. So a unique constraint violation is to be expected.
I then added the line
statement.execute("DROP TABLE IF EXISTS charge");
to createChargeTable(), above the line that creates the table. The code then ran successfully multiple times using either version of the SQLite JDBC driver.
This bug has now been fixed in sqlite-jdbc version 3.15.1, so the fix is therefore to upgrade to this version or later.
After you create a prepared statement, you should close it and not use it again. I don't see it in your code, but you stated: "which happens when I call the same preparedStatement a second time".
Your 'ps' variable should be a local variable, declared in a try-with-resource block such as:
try (PreparedStatement ps = connection.prepareStatement("INSERT INTO charge VALUES(?, ?, ?);")) {
ps.setString(1, username);
ps.setDate(2, DateConvert.toSQLDate(Date.valueOf(LocalDate.MIN)));
ps.setDouble(3, amount);
ps.executeUpdate(); //Line 170
ps.clearParameters();
System.out.println("Complete");
}
That way it can't be used after its been closed.
Java application to insert student scores and type of test taken
MySql tables tests table and scores tables
I need to update both tables with a single click of the "Update" button. How do I get the tests.test_id value to to inserted on the scores.test_id.
Here is what I have tried so far, however only the test table gets updated.
String subjectCode = SubjectCombo.getSelectedItem().toString(); //gets value selected from subject code JCombobox
String testType = AssesmentCombo.getSelectedItem().toString();//gets value selected from assesment code JCombobox
ResultSet rst = null;
try {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/resultchecker_db","edunge","Ihu18om#031988");
st = con.createStatement();
String query4 = "INSERT INTO tests (subject_id, type, test_id) VALUES (?,?,NULL)"; //query to update tests table
ps = con.prepareStatement(query4);
ps.setString(1, subjectCode);
ps.setString(2, testType);
ps.execute();
} catch (SQLException e1) {
JOptionPane.showMessageDialog(null, e1);
}
try {
if (rst.next()){
JOptionPane.showMessageDialog(null, "Student record updated");
}
} catch (HeadlessException e1) {
JOptionPane.showMessageDialog(null, e1);
} catch (SQLException e1) {
JOptionPane.showMessageDialog(null, e1);
}
try {
con.close();
st.close();
rst.close();
} catch (SQLException e1) {
JOptionPane.showMessageDialog(null, e1);
}
//This successfully updates the test table
I also tried to create another mysql connection on the actionlistener that will take the value of test.test_id and insert it to scores table, with below code.
try {
Connection con2 = DriverManager.getConnection("jdbc:mysql://localhost:3306/resultchecker_db","edunge","Ihu18om#031988");
Statement st2 = con2.createStatement();
String query5 = "SELECT test_id FROM tests ORDER BY test_id DESC LIMIT 1;";
rst2 = st2.executeQuery(query5);
} catch (SQLException e1) {
JOptionPane.showMessageDialog(null, e1);
}
try {
while(rst2.next()){
label.setText(rst2.getString(1)); //used a label to see if the auto_increment values is received.
}
} catch (SQLException e1) {
JOptionPane.showMessageDialog(null, e1);
}
Both connection codes to MySQL DB are all in the
"update" actionlistener.
The aim of this is to build a simple student result checker application, for different subjects (with continuous Assessments and Exam) and scores. I would also welcome any advice on building a better MySQL database
The approach to query the generated ID might not always work in case of concurrency, e.g. multiple users using the application at the same time. It depends on the configured concurrency isolation level. If two transactions first both insert the test and then both query the ID one transaction will get the ID of the test that the other transaction inserted.
How to get a generated ID is answered in this post. These are the main things to do according to the post:
PreparedStatement statement = connection.prepareStatement(SQL_INSERT, Statement.RETURN_GENERATED_KEYS);
...
ResultSet generatedKeys = statement.getGeneratedKeys()
I don't recognize any problems concerning your database schema, but you wouldn't have to think about how to get the ID if you used an ORM-framework like Hibernate.
I am working on Java Application and trying so hard to update record in SQLite database but it doesn't work .. btw it doesn't give me any exceptions or errors
String sql="update Food_Fresh set available=? where Type_ID =?";
st=con.prepareStatement(sql);
st.setInt(1, 1);
st.setInt(2, num);
st.executeUpdate();
st.close();
What's the problem ?!
UPDATE
yes , the initialization of sql
try{
Class.forName("org.sqlite.JDBC");
Connection con=DriverManager.getConnection("jdbc:sqlite:C:\\Users\\Shatha2012\\Desktop\\Core\\IT\\Graduation Project\\Code\\New folder\\Food\\src\\Food\\Food.sqlite");
JOptionPane.showMessageDialog(null, "DONE");
return con;
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null, e);
return null;
}
}
and the committing is set as auto commit
Maybe there are no records in your database with Type_ID = num?
Check the value returned from executeUpdate()
int i = st.executeUpdate();
it will show you the number of records updated
public boolean saveScore1(Score obj) {
boolean returnValue = false;
String sql = "insert into score(e_id,u_id,u_score,y_id,b_id) values(?,?,?,?,?)";
try {
Connection connection = DBConnectionHandler.getConnection();
PreparedStatement ps = connection.prepareStatement(sql);
ps.setInt(1, obj.getEId());
ps.setInt(2, obj.getUId());
ps.setString(3, obj.getUScore());
ps.setInt(4, obj.getYId());
ps.setInt(5, obj.getBId());
int i = ps.executeUpdate();
if (i > 0) {
returnValue = true;
}
} catch (Exception e) {
e.printStackTrace();
}
return returnValue;
}
Here are the three table i'm using
Examtable: e_id integer(auto increment) pk,e_name varchar
UserTable: u_id integer(auto increment)pk,u_name varchar
ScoreTable: s_id integer(auto increment)pk ,u_id integer fk, e_id integer fk, u_score
I want to send multiple data to score table at a time with one sql query for same u_id but different e_id, beacuse e_id will contains different value like B.B.A,M.B.A, B.sc, M.sc etc. So one user can have different exam pass.
I'm using above java code to insert but i just take the last value from front-end jsf form.
How can i send multiple rows for same u_id with different e_id at a time.
First of all, you don't insert data with a SQL query. A query is a SELECT statement.
Using JDBC, you can batch multiple insert statements, such that number of round trips to the database are reduced (for performance). Functionally, it is the same as inserting one row at a time.
Since you are inserting multiple rows, you probably want all to succeed, or all to fail, so you need to do your own commit or rollback.
Of course, since to do want to insert multiple score rows, your method should take a List<Score>.
public boolean saveScores(List<Score> scores) {
String sql = "insert into score(e_id,u_id,u_score,y_id,b_id) values(?,?,?,?,?)";
try (Connection connection = DBConnectionHandler.getConnection()) {
connection.setAutoCommit(false);
try {
try (PreparedStatement ps = connection.prepareStatement(sql)) {
for (Score score : scores) {
ps.setInt (1, score.getEId());
ps.setInt (2, score.getUId());
ps.setString(3, score.getUScore());
ps.setInt (4, score.getYId());
ps.setInt (5, score.getBId());
ps.addBatch();
}
ps.executeBatch();
}
connection.commit();
} catch (Exception e) {
connection.rollback();
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}