Rollback doesn't work in java - java

I have a method which does a simple mysql insert, when I tried to rollback the insert action as follow, on an error but it is not rollingback on errors, please assist me,
public void addFamer(FamerDTO famer) throws Exception {
Connection con = JDBCConnectionPool.getInstance().checkOut();
con.setAutoCommit(false);
try {
String generalFamerDataSQL = "INSERT INTO famers(famer_code, name_wt_initials, full_name, gender, "
+ "nic_or_passport_no, sc_possition, phone_home, phone_mobile, phone_office) VALUES(?,?,?,?,?,?,?,?,?)";
PreparedStatement insertFamerPS = con.prepareStatement(generalFamerDataSQL, PreparedStatement.RETURN_GENERATED_KEYS);
insertFamerPS.setString(1, famer.getFamerCode());
insertFamerPS.setString(2, famer.getNameWithInitials());
insertFamerPS.setString(3, famer.getNameInFull());
insertFamerPS.setString(4, famer.getGender());
insertFamerPS.setString(5, famer.getNICorPassportNo());
insertFamerPS.setString(6, famer.getSocietyPosission());
insertFamerPS.setString(7, famer.getHomePhone());
insertFamerPS.setString(8, famer.getMobilePhone());
insertFamerPS.setString(9, famer.getOfficePhone());
insertFamerPS.execute();
String famerRelations = "INSERT INTO org_reg_blk_soc_fmr(org_id, region_id, famer_id, block_id, soc_id) "
+ "VALUES (?,?,?,?,?)";
PreparedStatement famerRelationsPS = con.prepareStatement(famerRelations);
famerRelationsPS.setInt(1, famer.getOrganization().getOrg_id());
famerRelationsPS.setInt(2, famer.getRegion().getRegion_id());
famerRelationsPS.setInt(3, famerID);
famerRelationsPS.setInt(4, famer.getBlock().getBlockId());
famerRelationsPS.setInt(6, famer.getSociety().getSoc_id()); //intentionally made an error here to test, put index as 6 for 5
famerRelationsPS.execute();
con.commit();
} catch (Exception e) {
if (con != null) {
logger.info("Rolling back!");
con.rollback();
}
logger.error(e.getLocalizedMessage());
} finally {
con.setAutoCommit(true);
JDBCConnectionPool.getInstance().checkIn(con);
}
}
once this method is called with the required parameters as there is a error in the second insert statement I expected to rollback the first insert action. but thought the error is shown, a record is added to the data base by the first insert statement.

Just to check - what is the table type you're using? Last time I used MySQL, MyISAM tables didn't support transactions, meaning you have to used another table type e.g. InnoDB.

Related

Java JDBC Derby Syntax Error

Hi I have a problem with my syntax in my java code. I have a tableview which gets its data from a SQL database. I have created 3 tables in the database book, customer, order. When I click a button I want to take the selected books and add them to the order table.
Here is the code from the main program (calling the method from db):
if(table.getSelectionModel().getSelectedItems().iterator().hasNext()) {
db.insertOrder(new Bestellung(customerid,table.getSelectionModel().getSelectedItems().iterator().next()));
The table book is fixed. Just the two other tables customer,order are dynamic.
The problem:
I create the values in the order table like this
String ct = "CREATE TABLE Order (" + "Order_Id integer generated always as identity, " + "CUSTOMER_ID BIGINT" + "ISBN, CHAR(13) " + "PRIMARY KEY(Order_Id))";
and so on...
I insert into order table like this. (Here is the syntax problem in the String i That's the position where the compiler says it doesn't work..)
String i = "INSERT INTO ORDER(CUSTOMER_ID,ISBN), VALUES(?,?)";
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = DriverManager.getConnection(connString);
stmt = conn.prepareStatement(i);
conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
stmt.setLong(1, order.getCustomerId());
stmt.setString(2, order.getBuch().getISBN());
stmt.executeUpdate();
} catch (SQLException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
finally {
try {
if (stmt != null)
stmt.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
and here is the syntax error which I got
Syntax error: Encountered "ORDER" at line 1, column 13.
So how do I have to correct my syntax in the string i? Does anyone have any ideas?
INSERT INTO ORDER(CUSTOMER_ID,ISBN), VALUES(?,?)
^
The comma is superfluous. Also, in your CREATE TABLE
... + "ISBN, CHAR(13) " + ...
^
This comma is also extraneous.
If you want to use reserved words/keywords as Table name, you should:
MySQL: use ' , like : select * from 'Order'
Oracle, PostgreSQL: use " , like : select * from "Order"
But it is bad practice, try to change your table name.
You have another Error that answered by #Jim Garrison.

Struts2: Save SQL query in the database

In my Struts2 Java web application users are allowed to query the database. As an example, the user needs to get the employee details whose first name is equal to 'Charles'. Then s/he can select the report columns and criteria (firstname='Charles').
Once the user gives above inputs it need to save the relevant SQL query into the database.
e.g. SQL -> SELECT * FROM employee WHERE firstname='Charles'
Here is what I am trying in my action class.
try {
connection = DriverManager.getConnection(
SelectAction.getDatabase(), SelectAction.getUser(),
SelectAction.getPassword());
if (connection != null) {
System.out.println("Database connection established!");
stmt = connection.createStatement();
String sql = "INSERT INTO reports (report_id, sql) values ('" + reportId + "', '" + sqlQ + "');";
System.out.println("sql--->" + sql);
// Executing query
stmt.executeQuery(sql);
return SUCCESS;
} else {
System.out.println("----Failed to make connection!");
return ERROR;
}
} catch (SQLException e) {
System.out.println("Connection Failed!!");
e.printStackTrace();
return SUCCESS;
}
This is my insert query.
INSERT INTO reports (report_id, sql) values ('mynewreport', 'SELECT * FROM employee WHERE firstname='Charles'');
I am getting following error in my console.
ERROR: syntax error at or near "Charles"
I think here I am using a String so that the problem is with quotes('). I am using postgreSQL as database.
Any suggestions to solve this issue ?
Never use string concatenation of user supplied values to build a SQL statement.
Never use string concatenation of any non-integer values to build a SQL statement.
You will leave yourself open to SQL Injection attacks and/or SQL statement errors.
Hackers will love you for allowing them to steal all your data, and the nefarious ones will corrupt or delete all your data, while laughing maniacally at you on their way to the bank.
Use PreparedStatement and parameter markers.
String sql = "INSERT INTO reports (report_id, sql) values (?, ?)";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, reportId);
stmt.setString(2, sqlQ);
stmt.executeUpdate();
}

Unable to fix the error while inserting records into database using JDBC

public class StudentDataPersistence {
public void insertStudentInfo(Student student) {
String url = "jdbc:oracle:thin:#localhost:1521:XE";
String username = "system";
String password = "Data03#";
Connection connection = null;
//Statement statement = null;
try {
//Step 1 : Register JDBC driver
Class.forName("oracle.jdbc.driver.OracleDriver");
//Step 2 : Open a connection
System.out.println("Connecting to a selected database...");
connection = DriverManager.getConnection(url, username, password);
if (connection != null) {
System.out.println("Connected to oracle");
}
//Step 3 : Write code to map Java Object to the Student_Info table
System.out.println("Inserting records into the database");
statement = connection.createStatement();
String sql = "insert into Student_Info " +
"VALUES(student.getName(),student.getRoll_no(),student.getAddress(),student.getPhone_no())";
statement.executeUpdate(sql);
System.out.println("Inserted student information into the database");
} catch (SQLException se) {
//handle errors for JDBC
se.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
//Handle errors for Class.forName
} finally {
System.out.println("Inside the finally block");
//finally block used to close resources
try {
statement.close();
} catch (SQLException se) {
se.printStackTrace();
}
try {
connection.close();
} catch (SQLException se) {
se.printStackTrace();
}
}
System.out.println("!GoodBye");
}
public static void main(String[] args) {
Student student = new Student("Bavin", 1, "Umar Nagar", "89898989809");
StudentDataPersistence obj = new StudentDataPersistence();
obj.insertStudentInfo(student);
}
}
The error it shows it :
Connecting to a selected database...
Connected to oracle
Inserting records into the database
java.sql.SQLException: ORA-00904: "STUDENT"."GETPHONE_NO": invalid identifier
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:189)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:242)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:554)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1478)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:888)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2076)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1986)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2697)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:1035)
at org.core.hibernate.reason.StudentDataPersistence.insertStudentInfo(StudentDataPersistence.java:52)
at org.core.hibernate.reason.StudentDataPersistence.main(StudentDataPersistence.java:80)
Inside the finally block
!GoodBye
All the answers (those of you who illustrate it with an oracle query) in reply were wrong.
Kindly do have a look at it before posting.
the correct one i got when i posted another thread regarding the same:
String query = "insert into Student_Info(name,roll_no,address,phone_no) VALUES('"+student.getName()+"',"+student.getRoll_no()+",'"+student.getAddress()+"','"+student.getPhone_no()+"')";
you have commented out your Statement object definition. So the statement object is unknown when you're using it.
uncomment this line:
//Statement statement;
And as earlier pointed out by #putaro, you need to quote certain parts of your SQL query.
String sql = "insert into Student_Info " +
"VALUES("+student.getName()+","+student.getRoll_no()+","+student.getAddress()+","+student.getPhone_no()+")";
This is to insert the actual object values into the query. Things within the quote would be inserted as it is.
Error ORA-00904 means Oracle does not know the identifier "STUDENT"."GETPHONE_NO" it looks like you are trying to insert some value to a column named "GetPhone_NO" to Table "Student" from your SQL. so you should check your SQL and table structure again
I see there are two problems in the code.
Currently your code is not using the student object while making the query. All student.getName() etc call taken as plain strings rather than method calls that returns the appropriate values.
Second it would be better to write the query in the following form. It will avoid silly errors because of the structure of the tables.
"INSERT INTO student_info(name,roll_no,address,phone) VALUES("+
student.getName()+"," +
student.getRoll_no()+","+student.getAddress()+","+student.getPhone_no()+")";
Even better is if you use prepared statement like
Try changing the query like
"INSERT INTO student_info(name,roll_no,address,phone) VALUES(?,?,?,?)"
and then set the parameter values.

Batch processing JDBC

I am practicing JDBC batch processing and having errors:
error 1: Unsupported feature
error 2: Execute cannot be empty or null
Property files include:
itemsdao.updateBookName = Update Books set bookname = ? where books.id = ?
itemsdao.updateAuthorName = Update books set authorname = ? where books.id = ?
I know I can execute about DML statements in one update, but I am practicing batch processing in JDBC.
Below is my method
public void update(Item item) {
String query = null;
try {
connection = DbConnector.getConnection();
property = SqlPropertiesLoader.getProperties("dml.properties");
connection.setAutoCommit(false);
if ( property == null )
{
Logging.log.debug("dml.properties does not exist. Check property loader or file name is spelled right");
return;
}
query = property.getProperty("itemsdao.updateBookName");
statement = connection.prepareStatement(query);
statement.setString(1, item.getBookName());
statement.setInt(2, item.getId());
statement.addBatch(query);
query = property.getProperty("itemsdao.updateAuthorName");
statement = connection.prepareStatement(query);
statement.setString(1, item.getAuthorName());
statement.setInt(2, item.getId());
statement.addBatch(query);
statement.executeBatch();
connection.commit();
}catch (ClassNotFoundException e) {
Logging.log.error("Connection class does not exist", e);
}
catch (SQLException e) {
Logging.log.error("Violating PK constraint",e);
}
//helper class th
finally {
DbUtil.close(connection);
DbUtil.closePreparedStatement(statement);
}
You are mixing together methods of Statement and PreparedStatement classes:
(addBatch(String sql) belongs to Statement and cannot be called on a PreparedStatement or CallableStatement
addBatch() is to be used with PreparedStatement (as your tutorial shows).
Oracle implements both it's own and standard (JDBC 2.0) batch processing. From the Standard Update Batching docs:
In Oracle JDBC applications, update batching is intended for use with
prepared statements that are being processed repeatedly with different
sets of bind values.

Inserting email in SQLite database using JDBC

I am trying to insert an email ID to a table in my SQLite3 Database. In my case it successfully creates the table but gives an error while inserting a record in it - "near "#gmail": syntax error". How can i resolve this ? Here is the code -
public void insertData(String emailId, double gtse, long receivedDate) throws ClassNotFoundException, SQLException{
Class.forName("org.sqlite.JDBC");
Connection connection = null;
try
{
// create a database connection
connection = DriverManager.getConnection("jdbc:sqlite:testdb.sqlite");
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
ResultSet result = statement.executeQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='T1'");
if(!result.next()){
statement.executeUpdate("create table T1 (email TEXT, gtse REAL, receiveddate DATE)");
statement.executeUpdate("insert into T1 values(" + emailId + ", "+ gtse +", "+ receivedDate +")");
}
else{
}
}
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);
}
}
}
Your core error is that for the insert query you are not enclosing the values to be inserted, in quotes. Your query, after construction, looks something like this:
insert into T1 values(whatever#gmail.com, emailtexthere, 04-07-2013)
When it should be something like this:
insert into T1 values('whatever#gmail.com', 'emailtexthere', '04-07-2013')
The SQL parser chokes while trying to parse your current query, because the syntax is incorrect. The solution to this problem is not simply to enclose the values in quotes though, but rather to use prepared statements. This is because the way you are constructing your query right now is vulnerable to SQL injection attacks. Here is an example of using a prepared statement:
PreparedStatement pStmt = conn.prepareStatement(
"INSERT INTO T1 VALUES(?, ?, ?)");
pStmt.setString(1, emailId);
pStmt.setString(2, gtse);
pStmt.setDate(3, receivedDate);
pStmt.execute();

Categories