The database update method that I'm working on in my java program, doesn't update the database. Only if I run the read method inside the same class, it will show the updated version of the database but it doesn't actually update the database.
What I do is I run the unit_elimination(2) method inside my main class and then it doesn't update the database ( it should turn the status column of the row with ID=1 inside main_table to 2 but it stays the same in the database ) . Then I use the showname method to read the table and it shows the updated number but the database isn't actually getting updated.
package com.company;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.*;
public class Stdn implements AutoCloseable{
private Connection connection;
private PreparedStatement preparedStatement;
private ResultSet resultSet;
public Stdn() throws SQLException {
connection = DriverManager
.getConnection("jdbc:mysql://localhost:1522/juni_project" , "root", "password");
connection.setAutoCommit(false);
}
public void showName(String A , String B) throws SQLException{
preparedStatement = connection.prepareStatement("select "+ A + " from " + B + ";" );
resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getString(1));
}
}
public void update(String A , String B , int C , int D) {
try{
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE "+ A + " SET " + B + " =? WHERE ID = ? ;");
preparedStatement.setInt(1,C);
preparedStatement.setInt(2, D);
preparedStatement.executeUpdate();
}
catch (SQLException e){
System.out.println( " Could not update data to the database " + e.getMessage());
}}
public void unit_elimination(int X) throws SQLException {
update("main_table" ,"status", X , 1 );
}
#Override
public void close() throws Exception {
preparedStatement.close();
connection.close();
}}
Can you please help me find where the problem is I've been stuck on this for a few days and have little time to spare.
You disable auto-commit after creating the connection. This means you have to explicitly commit (using connection.commit()) before changes are visible to other transactions. And, IIRC, MySQL or MySQL Connector/J will rollback the transaction if it is still active when you close the connection.
In other words, your changes are 1) never visible to other transactions and 2) once you close the connections, your changes are gone.
TL;DR: Add a connection.commit() where your unit-of-work is complete and you want the changes to become permanent. Or consider if for your program using auto-commit is good enough, and remove the connection.setAutoCommit(false); from your code.
Related
Here is my application's code to create the database, connect to it, and make a table in the database called Accounts.
package eportfolio.application;
import java.io.File;
import java.io.FileWriter;
import javax.swing.JOptionPane;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
/**
*
* #author valeriomacpro
*/
public class HomePage extends javax.swing.JFrame {
public static String username;
public static String password;
public static int SelectedPost;
/**
* Creates new form HomePage
*/
public static boolean doesTableExists (String tableName, Connection conn)
throws SQLException {
DatabaseMetaData meta = conn.getMetaData();
ResultSet result = meta.getTables(null, null, tableName.toUpperCase(), null);
return result.next();
}
public HomePage() {
initComponents();
try
{
String databaseURL = "jdbc:derby:eportdatabase;create=true";
Connection con = DriverManager.getConnection(databaseURL);
Statement st = con.createStatement();
if (!doesTableExists("Accounts", con))
{
String sql = "CREATE TABLE Accounts (Username varchar(250), Password varchar(250)) ";
st.execute(sql);
System.out.println("Table Does Not Yet Exist!");
}
else if(doesTableExists("Accounts", con)) {
System.out.println("Table Already Exists!");
}
con.close();
} catch(SQLException e) {
do {
System.out.println("SQLState:" + e.getSQLState());
System.out.println("Error Code:" + e.getErrorCode());
System.out.println("Message:" + e.getMessage());
Throwable t = e.getCause();
while(t != null) {
System.out.println("Cause:" + t);
t = t.getCause();
}
e = e.getNextException();
} while (e != null);
}
}
Additionally, here is my code that interacts with the Accounts table.
try
{
String databaseURL = "jdbc:derby:eportdatabase;";
Connection con1 = DriverManager.getConnection(databaseURL);
Statement st = con1.createStatement();
String sql = " INSERT INTO Accounts VALUES ('"+txtNewUsername.getText()+"','"+txtNewPassword.getText()+"') ";
st.executeUpdate(sql);
JOptionPane.showMessageDialog(null, "Account Info Saved!");
txtNewUsername.setText("");
txtNewPassword.setText("");
txtNewConfirm.setText("");
}
When I run the application, the code works fine. However, if I open DBeaver and connect it to my database, then the following error message comes up. Does not come up if DBeaver is closed, even if it is connected to the database.
Message:Failed to start database 'eportdatabase' with class loader jdk.internal.loader.ClassLoaders$AppClassLoader#45ee12a7, see the next exception for details.
Cause:ERROR XJ040: Failed to start database 'eportdatabase' with class loader jdk.internal.loader.ClassLoaders$AppClassLoader#45ee12a7, see the next exception for details.
Cause:ERROR XSDB6: Another instance of Derby may have already booted the database /Users/(username)/NetBeansProjects/ePortfolio Application/eportdatabase.
SQLState:XSDB6
Error Code:45000
Message:Another instance of Derby may have already booted the database /Users/(username)/NetBeansProjects/ePortfolio Application/eportdatabase.
Cause:ERROR XSDB6: Another instance of Derby may have already booted the database /Users/(username)/NetBeansProjects/ePortfolio Application/eportdatabase.
Why is this? Am I connecting the Database to DBeaver incorrectly? Or am I coding the database incorrectly in Netbeans? It could be that my drivers and db derby version are old, but I have not been able to find help on that online either. Also important to know that the table does show up in DBeaver, but does not update. I have to delete the database folder in my application's folder every time I want to use the application with DBeaver open. Any help appreciated.
By using this line of code:
String databaseURL = "jdbc:derby:eportdatabase;";
you are using Derby in the "embedded" configuration. With Embedded Derby, only one Java application at a time can use the database. Other applications that try to use it concurrently are rejected with the message
Another instance of Derby may have already booted the database
as you saw when you tried it.
There are other configurations in which Derby can be deployed and run; specifically there is a Client-Server configuration in which multiple applications may all run as clients, and may connect to the same Derby server, allowing the applications to run concurrently.
To learn more about these aspects of Derby, start here: https://db.apache.org/derby/docs/10.15/getstart/cgsquck70629.html
ConnectionClass:
Here I used stm.execute but I'm not getting an error. I also used executeUpdate but I'm also getting an error.
package com.company;
import java.sql.*;
class ConnectionClass {
private static Connection con = null;
private static Statement stm = null;
private static ConnectionClass connectionClass;
public void createConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql", "root", "root");
}
catch (Exception e) {
e.printStackTrace();
}
}
public void createTable() {
String Table_Name = "BOOK";
try {
stm = con.createStatement();
DatabaseMetaData dbm = con.getMetaData();
ResultSet rs = dbm.getTables(null, null, Table_Name, null);
if (rs.next()) {
System.out.println("Table" + Table_Name + "Already created");
} else {
String sql = "CREATE TABLE" + Table_Name + "(ID VARCHAR(200), title VARCHAR(200),author varchar(100),publisher varchar(100)";
stm.executeLargeUpdate(sql);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public ConnectionClass() {
createConnection();
createTable();
}
}
MainClass:
Here I think the main class is working properly.
package com.company;
public class Main {
public static void main(String[] args) throws Exception {
ConnectionClass connectionClass = new ConnectionClass();
}
}
ERROR:
The method executeLargeUpdate was added in Java 8 / JDBC 4.2 and judging by the error it has not been implemented in the MySQL Connector/J version you are using.
The solution is simple: don't use any of the Large methods in the API, and instead use executeUpdate, or - better in the case of DML - execute. Alternatively, update to a newer version of MySQL Connector/J, as executeLargeUpdate is implemented in newer versions of MySQL Connector/J (eg 5.1.46, but at least 5.1.37 (the version that added support)).
You will also need to address the syntax error pointed out by Adil.
You have a syntax error in your query. You current SQL Query:
String sql = "CREATE TABLE" + Table_Name + "(ID VARCHAR(200), title VARCHAR(200),author varchar(100),publisher(100)";
Corrected SQL Query:
String sql = "CREATE TABLE" + Table_Name + "(ID VARCHAR(200), title VARCHAR(200),author varchar(100),publisher varchar(100)";
(You are asking mysql to create a column publisher, but where's the datatype? Simply specify the datatype and it will work.)
EDIT:
So, finally wrapping up this question, let's have a look at what Ora Docs have to say about this:
executeLargeUpdate:
default long executeLargeUpdate(String sql) throws SQLException
Executes the given SQL statement, which may be an INSERT, UPDATE, or DELETE statement or an SQL statement that returns nothing, such as an SQL DDL statement.
This method should be used when the returned row count may exceed Integer.MAX_VALUE - A constant holding the maximum value an int can have, 2^31-1.
Note:This method cannot be called on a PreparedStatement or CallableStatement.
The default implementation will throw UnsupportedOperationException. This method is introduced since JDK 1.8
Also note the above point as stated in the docs. The default implementation is to throw an UnsupportedOperationException. This means that different JDBC drivers can have different implementations of Statement class. They can either implement it or leave it unimplemented, and if you invoke the method in 2nd case, the method will throw an UnsupportedOperationException, as stated in the docs.
By checking the oracle docs for this method, you can get more information about it. So the possibility could be that the driver version you are using is not supporting this method, so please update tot eh latest version of this driver and try it out.
I'm not sure why my program isn't creating the table but I also need some ideas on how to fill the table with code like this once it's created? I need to add two more tables to this database too.
This is the error I'm getting :
java.sql.SQLSyntaxErrorException: Table/View 'PIZZASIZE' does not exist.
Caused by: ERROR 42X05: Table/View 'PIZZASIZE' does not exist.
Caused by: java.lang.RuntimeException: Exception in Application start method
Caused by: javafx.fxml.LoadException: file:/C:/Users/Allie/Documents/NetBeansProjects/Pizzeria_AllieBeckman/dist/run1674141987/Pizzeria_AllieBeckman.jar!/pizzeria_alliebeckman/FXMLDocument.fxml
This is the code that's supposed to create the table:
// connect to the derby URL using the given username and password
connect = DriverManager.getConnection("jdbc:derby://localhost:1527/pizzeria;create=true", connectProps);
// current url for pre created database "jdbc:derby://localhost:1527/pizza"
// if connection is successful print that it succeeded.
System.out.println("database created");
stmt = connect.createStatement();
String sqlCreate = "CREATE TABLE PIZZASIZE "
+ "(id int NOT NULL, "
+ "size char(20) NOT NULL, "
+ "PRIMARY KEY (id))";
stmt.execute(sqlCreate);
Depending on the IDE you are using you could manually create the table in a console without going through the trouble of writing it in code. Here are some examples of how you could get the information from the tables.
Connection conn = CreatingDerbyDJB.dbConnection();
try{
String query = "INSERT INTO Items (Name,Color,ItemName,SchoolName, Description) VALUES(?,?,?,?, ?)";
PreparedStatement pstmt = conn.prepareStatement(query);
pstmt.execute();
conn.close();
}catch(Exception e)
{
e.printStackTrace();
} }
Here is what the Connection class should look like:
package main;
import java.sql.Connection;
import java.sql.DriverManager;
import javax.swing.JOptionPane;
public class CreatingDerbyDJB
{
public static final String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
public static final String JDBC_URL = "jdbc:derby:LostAndFoundDB";
public static Connection dbConnection()
{
try
{
Class.forName(DRIVER).newInstance();
Connection c = DriverManager.getConnection(JDBC_URL);
return c;
}catch(Exception e)
{
JOptionPane.showMessageDialog(null, e);
return null;
}
}
}
Approve this answer if this helped you, I'd be happy to explain things if it does not make sense. :)
In the example below showing how to use Java's SQL library, Class.forName() is called without a variable to save a reference to the object. What is the purpose of doing this if you cannot manipulate it later? I've seen that line written in various examples of the SQL library.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Sample
{
public static void main(String[] args) throws ClassNotFoundException
{
// load the sqlite-JDBC driver using the current class loader
Class.forName("org.sqlite.JDBC");
Connection connection = null;
try
{
// create a database connection
connection = DriverManager.getConnection("jdbc:sqlite:sample.db");
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
statement.executeUpdate("drop table if exists person");
statement.executeUpdate("create table person (id integer, name string)");
statement.executeUpdate("insert into person values(1, 'leo')");
statement.executeUpdate("insert into person values(2, 'yui')");
ResultSet rs = statement.executeQuery("select * from person");
while(rs.next())
{
// read the result set
System.out.println("name = " + rs.getString("name"));
System.out.println("id = " + rs.getInt("id"));
}
}
catch(SQLException e)
{
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
}
finally
{
try
{
if(connection != null)
connection.close();
}
catch(SQLException e)
{
// connection close failed.
System.err.println(e);
}
}
}
}
It makes the class initializer run - which in the case of JDBC drivers used to be the way that the driver would register itself with DriverManager. In modern Java, JDBC drivers are usually found using the service provider API.
From the docs:
Applications no longer need to explictly load JDBC drivers using Class.forName(). Existing programs which currently load JDBC drivers using Class.forName() will continue to work without modification.
I am trying to insert data into Derby embedded database for my Desktop Application. But Derby is giving me error of Schema Not found error.
I have tried to solve error by creating schema as per username, but does not solve my problem. I searched internet, but none of given solution solved my problem.
package derbyd.ui;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class AddStudent extends javax.swing.JFrame {
private void bt_saveActionPerformed(java.awt.event.ActionEvent evt) {
String conURL = "jdbc:derby:myDB;create=true";
String user = "SOURABH";
String passwd = "pass";
Connection con = null;
Statement st = null;
String query;
ResultSet rs = null;
try
{
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
con = DriverManager.getConnection(conURL, user, passwd);
st = con.createStatement();
System.out.println("Connection established");
query = "INSERT INTO SOURABH.MyTable VALUES('"+txt_name.getText()+"','"+txt_surname.getText()+"')";
st.executeUpdate(query);
System.out.println("Added Successfully");
}
catch(Exception e)
{
System.out.println("Error ->"+e);
}
}
}
According to the Frequently Asked Questions of Apache Derby, you will see that:
A schema is only created by CREATE SCHEMA or creating an object (table etc.) in that schema (this is implicit schema creation).
In your code, you need create the table first and then work like a charm.
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
con = DriverManager.getConnection(conURL, user, passwd);
st = con.createStatement();
System.out.println("Connection established");
st.executeUpdate("CREATE TABLE MyTable" +
"(name VARCHAR(255), surname varchar(255))");
System.out.println("Table created");
query = "INSERT INTO SOURABH.MyTable VALUES(" +
"'" + txt_name.getText() + "','" + txt_surname.getText() + "')";
st.executeUpdate(query);
System.out.println("Added Successfully");
The output is:
Connection established
Table created
Added Successfully
If you run this statement more than once, you'll get an error because the table already exists. To deal with that, here.
the easiest solution is to configure your database properties and make schema the same as user name but in capital litters
ex:
schema APP
user app
hope my answer can help.