I have set the stdImage to not null in database, when i don't insert the image it throws an error but still con.commit() work out and data instead of rollback() save to database without image can someone solve the logical error in this code please. Actually rollback() is not working. I will be thankful.
public void stdSave(String stdID, String stdName, String fName, String sSec, String contactNo, Date bdate, String address, byte[] image) throws RemoteException, SQLException {
String stdQuery = "INSERT INTO dbo.StudentTable (stID, stName, stFName, classSection,"
+ "contact, date, pAddress) VALUES (?, ?, ?, ?, ?, ?, ?)";
String imgQuery = "INSERT INTO dbo.StdImage (stdID, stdImage) VALUES (?, ?)";
Savepoint save = null;
try {
try(PreparedStatement stmt = con.prepareStatement(stdQuery);
PreparedStatement stmt1 = con.prepareStatement(imgQuery)) {
con.setAutoCommit(false);
save = con.setSavepoint();
stmt.setString(1, stdID);
stmt.setString(2, stdName);
stmt.setString(3, fName);
stmt.setString(4, sSec);
stmt.setString(5, contactNo);
stmt.setDate(6, bdate);
stmt.setString(7, address);
stmt.execute();
stmt1.setString(1, stdID);
stmt1.setBytes(2, image);
stmt1.execute();
}
}
catch(Exception e) {
try {
con.rollback(save);
}
catch (Exception e1) {
JOptionPane.showConfirmDialog(null, "Cannot add the student to database " + e);
}
}
con.commit();
}
You are calling con.commit(); after the try-catch block, and since your catch all the exceptions, you always calls commit.
You should probably move the commit inside the try block:
...
con.commit();
}
catch(Exception e) {
try {
con.rollback(save);
}
catch (Exception e1) {
JOptionPane.showConfirmDialog(null, "Cannot add the student to database " + e);
}
}
Never do con.commit() in catch block, this can lead to unintended commits. Move con.commit() to your try block.
Next, please see that you are doing rollback to a savepoint, but savepoint is null. It is not initialzed.
con.rollback(save); is done but here save=null.
Either simply do con.rollback() or initialialize the savepoint and then rollback upto it.
Related
I'm working on a javafx project where a user can register as either a driver or a client. For this, I created 3 tables in a mysql database, a general one for all users and 2 specific ones for the drivers and the clients. When a new user registers he is placed in the database_user table and, depending on his selected role, he is also placed in either database_client or database_driver. The problem is that the specific tables should have a column storing the primary key value (autoincrement value) from the general table, for easier communication.
public static void registerClient(ActionEvent event, String username, String password, String role, String name, int age, String gender, String email)
{
/*
these variables are the connections to the mysql database
*/
Connection connection = null;
PreparedStatement psInsert = null;
PreparedStatement psInsertClient = null;
PreparedStatement psCheckUserAlreadyExists = null;
//PreparedStatement psCheckEmailAlreadyUsed = null;
ResultSet resultSet = null;
try{
/*
this will attempt to establish a connection with the db
*/
connection = DriverManager.getConnection("jdbc:mariadb://lazarov.go.ro:3306/RideShare", "root", "chocolate");
psCheckUserAlreadyExists = connection.prepareStatement("SELECT * FROM database_user WHERE username = ?");
psCheckUserAlreadyExists.setString(1, username);
//psCheckEmailAlreadyUsed = connection.prepareStatement("SELECT * FROM user_database WHERE email = ? ");
//psCheckEmailAlreadyUsed.setString(7, email);
resultSet = psCheckUserAlreadyExists.executeQuery();
/*
check if the resultSet is empty
if true => username already taken => notify user about this
*/
if(resultSet.isBeforeFirst())
{
System.out.println("Username already taken!");
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setContentText("User already exists!");
alert.showAndWait();
}
else
{
psInsert = connection.prepareStatement("INSERT INTO database_user (username, password, role, name, age, gender, email) VALUES (?, ?, ?, ?, ?, ?, ?)");
psInsert.setString(1, username);
psInsert.setString(2, password);
psInsert.setString(3, role);
psInsert.setString(4, name);
psInsert.setInt(5, age);
psInsert.setString(6, gender);
psInsert.setString(7, email);
psInsert.executeUpdate();
ResultSet rs = null;
psInsert = connection.prepareStatement("SELECT max(user_id) FROM database_user");
rs = psInsert.executeQuery();
// driver specific
int userId = resultSet.getInt("max(user_id)"); // this is where the error occurs
//Connection connectionDriver = null;
psInsertClient = connection.prepareStatement("INSERT INTO database_client (user_id, ride_requested, location, destination, corresponding_driver_id) VALUES (?, ?, ?, ?, ?)");
psInsertClient.setInt(1, userId);
psInsertClient.setBoolean(2, false);
psInsertClient.setString(3, null);
psInsertClient.setString(4, null);
psInsertClient.setInt(5, 0);
changeScene(event, "client.fxml", "RideShare - Client", username, role, name, age, gender, email);
}
}catch (SQLException e)
{
e.printStackTrace();
}finally {
/*
close db connections to avoid memory leaks
*/
if(resultSet != null)
{
try{
resultSet.close();
}catch (SQLException e)
{
e.printStackTrace();
}
}
if(psCheckUserAlreadyExists != null)
{
try{
psCheckUserAlreadyExists.close();
}catch (SQLException e)
{
e.printStackTrace();
}
}
if(psInsert != null)
{
try {
psInsert.close();
}catch (SQLException e)
{
e.printStackTrace();
}
}
if(psInsertClient != null)
{
try {
psInsertClient.close();
}catch (SQLException e)
{
e.printStackTrace();
}
}
if(connection != null)
{
try{
connection.close();
}catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
If I try to create a new user, the user is added in the database_user correctly, but throws the error "wrong row position" when trying to store it in the "database_client" as well. How can I successfully get the last autoincremented value from the general table?
I've encountered an some inconsistencies regarding the results from an SQL query.
Here is the query which I'm using as a prepared statement.
delete ROLE_USER_MAP
from ROLE_USER_MAP inner join ROLE_MANAGER on ROLE_USER_MAP.R_ID=ROLE_MANAGER.R_ID
where ROLE_USER_MAP.U_ID= ? and ROLE_MANAGER.M_ID= ?
Here is how I calling the prepared statement in my Java application.
public void deleteRoles(String mID, String uID) throws OperationFailedException
{
Connection conn = null;
try
{
conn = this.getConnection();
this.deleteRoles(mID, uID, conn);
}
catch (Exception e)
{
AdminLogger.error(this.getClass(), e);
throw new OperationFailedException("Failed to remove roles for user.");
}
finally
{
try
{
conn.close();
}
catch (Exception e)
{
}
}
}
private void deleteRoles(String mID, String uID, Connection conn) throws SQLException
{
PreparedStatement stmt = null;
try
{
stmt = *retrieving ps*
stmt.setString(1, uID);
stmt.setString(2, mID);
int i = stmt.executeUpdate(); // returns 1 here
if (i < 1)
{
throw new SQLException("Failed to remove roles for user.");
}
} finally
{
stmt.close();
}
}
It runs fine locally and in SSMS with all rows fitting the where clause being deleted but when I try to deploy it to my hosted server, only the first row in the table is being deleted.
Can anyone help me with this?
Thanks in advance.
I can't execute the update query on JDBC with where clause. I want to execute the query by concatenating some variables.
protected void updateEmail(String Email, String Username) {
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost/project", "root", "");
String query = "update access set email=" + Email + " where username=" + Username;
Statement st = conn.createStatement();
st.executeUpdate(query);
} catch (SQLException ex) {
System.out.println(ex);
} finally {
try {
conn.close();
} catch (SQLException ex) {
}
}
}
It says:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'bhusal1' in 'where clause'
String should be between two quotes 'name' instead of your way you have to use PreparedStatement instead to avoid syntax error or SQL Injection :
String query = "update access set email=? where username=?";
PreparedStatement ps = con.prepareStatement(query);
ps.setString(1, email);
ps.setString(2, name);
ps.executeUpdate();
This is most likely a problem with concatenation of the request. The approach you use is extremely bad and can cause any problems (including security).
To avoid problems, use PrepareStatement when you need to submit sql query parameters.
Here's an example that should solve your problem:
void updateEmail(String email,String username) {
try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/project", "root", "")) {
String query = "update access set email = ? where username = ?";
try (PreparedStatement statement = connection.prepareStatement(query)) {
statement.setString(1, email);
statement.setString(2, username);
statement.executeUpdate();
}
}
catch (SQLException e) {
System.out.println(e);
}
}
You should put your variables email and username between quotes in the where clause to be able to do the update query
I'm trying to record String variables into a database in a MySQL statement in Java.
I've read this and this but I couldn't succeed.
Here is my code:
public void registerUser( String userName, String password ) {
try {
String insertQuery = "INSERT INTO Credentials ('11', name, pass) VALUES('11', ?, ?)";
pstmt = connection.prepareStatement(insertQuery);
pstmt.setString(2, userName);
pstmt.setString(3, password);
pstmt.executeUpdate();
// statement.executeUpdate("INSERT INTO Credentials VALUES(3, 'userName', 'password')");
} catch (SQLException e) {
e.printStackTrace();
} finally {
// close the connection when done
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}//END finally
}//END registerUser
As can you see, this code is getting two String values and it should put them into the database. But I can't find the proper solution.
Any ideas?
Thanks.
This:
pstmt.setString(2, userName);
pstmt.setString(3, password);
Needs to be:
pstmt.setString(1, userName);
pstmt.setString(2, password);
You are only setting two variables in your PreparedStatement, so you need to start counting at 1. The integers used in the setter methods need to match up with the question marks in your statement, not the parameter list of the given SQL string.
I am trying to insert question in question table and than getting that latest question id. I am trying to add options for it in other table named select_op. It inserts question successfully but not options. Even I am not getting any exception, method exits successfully.
int id=addQuestions(ques, survey_id);
if(id>0){
//not inserting anyvalue in database
String sql = "insert into select_op("+ "first,"+ "second,"+ "third,"+ "four,"+ "question_id)"+" values(?,?,?,?,?)";
try {
conn.setAutoCommit(false);
PreparedStatement pst = conn.prepareStatement(sql);
pst.setString(1,option1);
pst.setString(2,option2);
pst.setString(3,option3);
pst.setString(4,option4);
pst.setInt(5,id);
pst.addBatch();
System.out.println(pst.executeBatch());
}catch (BatchUpdateException e) {
try {
System.out.println(e);
conn.rollback();
} catch (Exception e2) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
//this function insert data successfully
public int addQuestions(String ques,String survey_id){
String sql = "insert into question(question,survey_id) values(?,?)";
int id = 0;
try {
conn.setAutoCommit(false);
PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
pstmt.setString(1,ques);
pstmt.setString(2,survey_id);
pstmt.addBatch();
pstmt.executeBatch();
ResultSet keys = pstmt.getGeneratedKeys();
keys.next();
id = keys.getInt(1);
keys.close();
conn.commit();
pstmt.close();
}
catch (BatchUpdateException e) {
try {
conn.rollback();
} catch (Exception e2) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return id;
}
Any Suggestion?
As Zaki Suggested
Are you missing a commit ?
I did commit.. Solved :)
Thanks
getGeneratedKeys() may not be supported in mysql (I've never seen it used or tried it).
But I do know this works: Executing the query select mysql_insert_id() returns the last auto increment value - use that instead of getGeneratedKeys().