can anyone please tell why the following update query which is working perfectly when executed directly from my SQLYog editor, but not executing from java. it is not giving any exception but not updating into the database.
this the update query
UPDATE hotel_tables SET hotel_tables.status='reserved' WHERE hotel_tables.section='pub' AND tableno='4' AND ('4' NOT IN (SELECT tableno FROM table_orders WHERE outlet='pub'))
Java code
public static void main(String[] args) throws Exception {
int update = new Dbhandler().update("UPDATE hotel_tables SET hotel_tables.status='reserved' WHERE hotel_tables.section='pub' AND tableno='4' AND ('4' NOT IN (SELECT tableno FROM table_orders WHERE outlet='pub'))");
}
public int update(String Query)throws Exception
{
try
{
cn=getconn();
stmt=(Statement) cn.createStatement();
n=stmt.executeUpdate(Query);
stmt.close();
}
catch(Exception e)
{
e.printStackTrace();
throw(e);
}
finally
{
cn.close();
}
return n;
}
public Connection getconn()
{
try
{
Class.forName(driver).newInstance();
String url="jdbc:mysql://localhost/kot?user=root&password=root";
cn=(Connection) DriverManager.getConnection(url);
}
catch(Exception e)
{
System.out.println("DBHandler ERROR:"+e);
}
return cn;
}
This is how I used to do it before I switched to Spring's JdbcTemplate framework. Maybe this will help. It looks very similar to yours.
public static int runUpdate(String query, DataSource ds, Object... params) throws SQLException {
int rowsAffected = 0;
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = ds.getConnection();
stmt = conn.prepareStatement(query);
int paramCount = 1;
for (Object param : params) {
stmt.setObject(paramCount++, param);
}
rowsAffected = stmt.executeUpdate();
conn.commit();
} catch (SQLException sqle) {
throw sqle;
//log error
} finally {
closeConnections(conn, stmt, null);
}
return rowsAffected;
}
There are some subtle differences. I do a commit, though autoCommit is the default.
Try like this:
DriverManager.getConnection("jdbc:mysql://localhost:3306/kot","root","root");
Related
There are two methods in which the PreparedStatement is used.
The first method is called in the second method.
First method:
protected List<String> findResultsByMandantId(Long mandantId) {
List<String> resultIds = new ArrayList<>();
ResultSet rs;
String sql = "SELECT result_id FROM results WHERE mandant_id = ?";
PreparedStatement statement = getPreparedStatement(sql, false);
try {
statement.setLong(1, mandantId);
statement.execute();
rs = statement.getResultSet();
while (rs.next()) {
resultIds.add(rs.getString(1));
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return resultIds;
}
Second method:
protected void findResultLineEntityToDelete(Long mandantId, String title, String context) {
List<String> resultIds = findResultsByMandantId(mandantId);
String [] resultIdsArr = resultIds.toArray(String[]::new);
ResultSet rs;
//String sql = "SELECT * FROM resultline WHERE result_id in (SELECT result_id FROM results WHERE mandant_id =" + mandantId + ")";
String sql = "SELECT * FROM resultline WHERE result_id in (" + String.join(", ", resultIdsArr)+ ")";
PreparedStatement statement = getPreparedStatement(sql, false);
try {
statement.execute();
rs = statement.getResultSet();
while (rs.next()) {
if (rs.getString(3).equals(title) && rs.getString(4).equals(context)) {
System.out.println("Titel: " + rs.getString(3) + " " + "Context: " + rs.getString(4));
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
The class in which both methods are located extends the JDBCBaseManager.
JDBCBaseManager:
private final String url = "jdbc:mysql://localhost:3306/database";
private final String userName = "root";
private final String password = "";
private Connection connection = null;
private PreparedStatement preparedStatement = null;
private int batchSize = 0;
public JDBCBaseManager() {
// Dotenv env = Dotenv.configure().directory("./serverless").load();
// url = env.get("DB_PROD_URL");
// userName = env.get("DB_USER");
// password = env.get("DB_PW");
}
public void getConnection() {
try {
if (connection == null) {
connection = DriverManager.getConnection(url, userName, password);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public PreparedStatement getPreparedStatement(String sql, boolean returnGeneratedKeys) {
try {
if (connection == null) {
getConnection();
}
if (preparedStatement == null) {
if (!returnGeneratedKeys) {
preparedStatement = connection.prepareStatement(sql);
} else {
preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
connection.setAutoCommit(false);
}
}
return preparedStatement;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public void closeConnection() {
try {
if (connection != null && !connection.isClosed()) {
System.out.println("Closing Database Connection");
connection.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public void startBatch(int batchSize) throws SQLException {
connection.setAutoCommit(false);
setBatchSize(batchSize);
}
public void commit() {
try {
if (connection != null && !connection.isClosed()) {
connection.commit();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public int getBatchSize() {
return batchSize;
}
public void setBatchSize(int batchSize) {
this.batchSize = batchSize;
}
The ResultSet in the second method still contains the results from the first method.
I already tried to close the connection and open it again before the second method is executed, but then I get the errors:
java.sql.SQLException: No operations allowed after statement closed.
java.sql.SQLNonTransientConnectionException: No operations allowed
after connection closed.
Can you tell me how to deal with the statement correctly in this case? Is my BaseManager incorrectly structured?
Here lies the error
public JDBCBaseManager() {
private PreparedStatement preparedStatement = null;
public PreparedStatement getPreparedStatement(String sql, boolean returnGeneratedKeys) {
try {
......
if (preparedStatement == null) {
if (!returnGeneratedKeys) {
preparedStatement = connection.prepareStatement(sql);
} else {
preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
connection.setAutoCommit(false);
}
}
return preparedStatement;
You build the prepare statement only the first time the method getPreparedStatement is called because only the first time the field preparedStatement is null. Every next time you call the method getPreparedStatement you receive the previous preparedStatement from the previous SQL and not the new one.
Remove the check for if (preparedStatement == null) {
You need to build a new preparedStatement every time you want to execute a new SQL.
I have a DAO which has method to insert entities into a MySQL database. That method takes a connection and entity as parameters. In Context.xml file, I set that connection will have defaultAutoCommit="false" property, so I don't need to set it inside DAO methods.
defaultAutoCommit="false"
#Override
public boolean insertCarCategory(Connection connection, CarCategory carCategory) {
int rowNum = 0;
String query = "INSERT INTO car_category values(?,?,?,?);";
try (Connection con = connection;
AutoRollback autoRollback = new AutoRollback(con);
PreparedStatement statement = con.prepareStatement(query)) {
statement.setString(1, carCategory.getCarCategory());
statement.setDouble(2, carCategory.getCostPerOneKilometer());
statement.setDouble(3, carCategory.getDiscount());
statement.setBytes(4, ImageUtil.imageToByte(carCategory.getCarCategoryImage()));
rowNum = statement.executeUpdate();
//if it used as transaction dont commit and close connection
autoRollback.commit();
} catch (SQLException e) {
LOGGER.error(e);
}
return rowNum > 0;
}
UserDao method that will be used In Service Layer
#Override
public boolean insertUser(Connection connection,User user) {
int rowNum = 0;
String query = "INSERT INTO user_info(login,userPassword,userType,userEmail)values(?,?,?,?);";
ResultSet keys = null;
try(Connection con = connection;
AutoRollback autoRollback = new AutoRollback(con);
PreparedStatement statement = con.prepareStatement(query,Statement.RETURN_GENERATED_KEYS)) {
statement.setString(1, user.getLogin());
statement.setString(2, PasswordUtil.generateStrongPasswordHash(user.getPassword()));
statement.setString(3, user.getUserType());
statement.setString(4, user.getUserEmail());
rowNum = statement.executeUpdate();
keys = statement.getGeneratedKeys();
if (keys.next()) {
user.setUserId(keys.getInt(1));
}
autoRollback.commit();
} catch (SQLException e) {
LOGGER.error(e);
} finally {
if (keys != null) {
try {
keys.close();
} catch (SQLException e) {
LOGGER.error(e);
}
}
}
return rowNum > 0;
}
I use AutoRollBack class that helps me to rollback transaction If commit is false
public class AutoRollback implements AutoCloseable {
private Connection conn;
private boolean committed;
public AutoRollback(Connection conn) throws SQLException {
this.conn = conn;
}
public void commit() throws SQLException {
conn.commit();
committed = true;
}
#Override
public void close() throws SQLException {
if(!committed) {
conn.rollback();
}
}
}
In the service layer, I use DAO methods. I get a connection from a connection pool and pass it to DAO methods.
private void insertCarUser(User user,CarCategory carCategory){
Connection connection = MySQLDAOFactory.getConnection();
categoryDao.insertCarCategory(connection,carCategory);
userDao.insertUser(connection,user);
}
How can I not close connection in one of the methods so that it can be used in the second?
Remove the try-with-resources in the various DAO methods, and instead apply try-with-resource immediately when obtaining a connection:
private void insertCarUser(User user,CarCategory carCategory){
try (Connection connection = MySQLDAOFactory.getConnection()) {
categoryDao.insertCarCategory(connection,carCategory);
userDao.insertUser(connection,user);
}
}
Similarly, you will want to move you transaction handling there, and not in your DAO methods if this operation needs to be atomic.
I have dao which methods should be within one transaction What is the best way to do it correctly?
Car dao has following method
public Car findCar(int numOfPas,String carCategory){
String query = "SELECT*FROM car_info WHERE numOfPas = ? AND carCategory=? AND carState='ready' ORDER BY RAND() LIMIT 1;";
Car foundCar = null;
ResultSet resultSet = null;
try (Connection connection = MySQLDAOFactory.getConnection();
PreparedStatement statement = connection.prepareStatement(query)){
statement.setInt(1,numOfPas);
statement.setString(2,carCategory);
resultSet =statement.executeQuery();
if(resultSet.next()){
foundCar = new Car();
foundCar.setCarId(resultSet.getInt("carId"));
foundCar.setCarCategory(resultSet.getString("carCategory"));
foundCar.setNumOfPas(resultSet.getInt("numOfPas"));
foundCar.setCarState(resultSet.getString("carState"));
foundCar.setCarName(resultSet.getString("carName"));
foundCar.setCarImage(manager.byteToImage(resultSet.getBytes("carImage")));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
return foundCar;
}
And Order Dao has following
#Override
public boolean insertOrder(Order order) {
int rowNum = 0;
String query = "INSERT INTO user_order(userId,carId,userAddress,userDestination,orderCost,orderDate) values(?,?,?,?,?,?)";
ResultSet keys = null;
try (Connection connection = MySQLDAOFactory.getConnection();
PreparedStatement statement = connection.prepareStatement(query,Statement.RETURN_GENERATED_KEYS)){
statement.setInt(1,order.getUserId());
statement.setInt(2,order.getCarId());
statement.setString(3, order.getUserAddress());
statement.setString(4, order.getUserDestination());
statement.setDouble(5,order.getOrderCost());
statement.setTimestamp(6, Timestamp.valueOf(order.getOrderDate()));
rowNum = statement.executeUpdate();
keys = statement.getGeneratedKeys();
if(keys.next()){
order.setOrderId(keys.getInt(1));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return rowNum>0;
}
How can I put these action in one transaction? I receive connection by Apache dhcp connection pool.
Edited
This is class
where I get connection
public class MySQLDAOFactory extends DAOFactory {
public static Connection getConnection(){
Connection conn = null;
try {
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:comp/env");
DataSource ds = (DataSource) envContext.lookup("jdbc/UsersDB");
conn = ds.getConnection();
} catch (NamingException | SQLException e) {
e.printStackTrace();
}
return conn;
}
#Override
public CarDao getCarDao() {
return new MySQLCarDao();
}
#Override
public UserDao getUserDao() {
return new MySQLUserDao();
}
#Override
public OrderDao getOrderDao() {
return new MySQLOrderDao();
}
#Override
public CarCategoryDao getCarCategoryDao() {
return new MySQLCarCategoryDao();
}
}
There are a lot of different ways to manage transactions. Given your code, the simplest way would be to:
in a try block:
Create your connection in the caller that wraps both calls
Execute connection.setAutoCommit(false)
Call each of the methods findCar() and insertOrder()
Call connection.commit();
in the catch block:
call connection.rollback()
The connection is not created outside those functions, so don't forget to remove the connection setup from each function.
What is the problem in this code? where it is update the all column values with the same last one .
public class dbconnection {
java.sql.Connection con;
java.sql.Statement st;
ResultSet rs;
public EncBean getConnection()throws SQLException{
EncBean encBean1 = new EncBean();
String v_url= "jdbc:oracle:thin:#192.168.2.138:1522:orcl2";
String v_username= "scott";
String v_password = "tiger";
try
{
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
con = DriverManager.getConnection(v_url,v_username,v_password);
System.out.println ("Connection to Oracle database was Established");
}
catch ( SQLException e)
{
e.printStackTrace();
}
return encBean1;
}
public EncBean selectRows()
{
EncBean encBean2 = new EncBean();
try
{
String SQLselect="select JOB_NAME from job";
st=con.createStatement();
rs=st.executeQuery(SQLselect);
while (rs.next()) {
encBean2.setName(rs.getString("JOB_NAME"));
}
}
catch ( Exception ex )
{
ex.printStackTrace();
}
return encBean2;
}
public void updateRows(String updatedname){
try
{
Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE);
ResultSet srs = stmt.executeQuery("select job_name from job " );
while (srs.next()) {
srs.updateString("job_name", updatedname);
srs.updateRow();
con.commit();}
System.out.println("An existing user was updated successfully!");}
catch(SQLException err){
System.out.println(err.getMessage());
}}}
This is the main
public class mainenc {
public static void main(String[] args) throws Exception{
dbconnection dbcon = new dbconnection();
EncBean encbeancon= dbcon.getConnection();
EncBean encBean5 = dbcon.selectRows();
enc concatinputs = new enc();
EncBean encBeanconcat = concatinputs.funconcat(encBean5.getName());
EncBean encBean4 = concatinputs.inputencryption(encBeanconcat.getConcatenatedData());
String vReserverbin= encBean4.getReversedBinary();
String ascistring= concatinputs.convertBinaryStringToString(vReserverbin);
dbcon.updateRows(ascistring);
}}
What is the problem in this code? where it is update the all column values with the same last one .
After updated method you should write list method again.
Try to take this example:
UPDATE tableB
SET tableB.value , tableA.value, tableB.value)
WHERE tableA.name = 'Joe'
It is kind of obvious: dbcon.updateRows(...) calls for the update method and that method does the job.
But as Erhan said, you don't get to see the result because you don't actually make use of updated records, e.g. show them etc. At least, you can check it out at the DB level if op is completed.
But I really disliked your comment:
plz can you do it for me?
You should do your own task and ask help when you need a hand. But never expect someone else to do your job mate.
This is the code i had written to save the data into the openoffice database.
but its giving error.i m not understanding y it is appearing.
package coop.data;
import java.sql.*;
/**
*
* #author spk
*/
public class Connectionsetting {
private static Connection con;
private static Statement sm;
private static ResultSet rs;
public static void close()
{
try
{
sm.close();
con.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void connection() {
String db_file_name_prefix = "/home/spk/Desktop/CooperHr/mydb.odb";
/*
If required change the file name if you are working in windows os
connection is in work
*/
try {
Class.forName("org.hsqldb.jdbcDriver");
System.out.println("Driver Found");
con=DriverManager.getConnection("jdbc:hsqldb:file"+db_file_name_prefix,"sa", "");
System.out.println("Connection Eshtablished");
// con.setAutoCommit(false);
sm=con.createStatement();
// sm = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
} catch (Exception e) {
e.printStackTrace();
}
}
public static int executeupdate(String query) {
//Execute & update block insert, update, delete statements
int bool = 0;
try {
bool=sm.executeUpdate(query);
} catch (Exception e) {
e.printStackTrace();
}
return bool;
}
public ResultSet executeQuery(String query) {
//Block Returns single resultset,,,sql statements such as sql select
ResultSet rs=null;
try {
rs = sm.executeQuery(query);
} catch (Exception e) {
e.printStackTrace();
}
return rs;
}
public boolean checkTableStatus(String tblName) {
String sql = "selec * from cat";
ResultSet rs=null;
boolean status = false;
int i = 0;
String allTableNames[] = new String[20];
try {
connection();
rs = sm.executeQuery(sql);
while (rs.next()) {
allTableNames[i] = rs.getString(0);
i++;
if (allTableNames[i].equals(tblName)) {
status = true;
break;
} else {
status = false;
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return status;
}
public static void main(String []args)
{
String query,s1,s2,s3,s4,s5,s6,s7,s8;
Connectionsetting cn=new Connectionsetting();
cn.connection();
s1="same";
s2="sam";
s3="923847";
s4="sam";
s5="sam";
s6="sam";
s7="sam";
s8="R01";
query="insert into Agency_Master values("+s1+","+s2+","+s3+","+s4+","+s5+","+s6+","+s7+","+s8+")";
cn.executeupdate(query);
}
}
This is the error..I m getting it when i trying to save the data into the database
Can any one plz tell me where i m wrong.
Thank you.
run:
Driver Found
Connection Eshtablished
java.sql.SQLException: user lacks privilege or object not found: AGENCY_MASTER
at org.hsqldb.jdbc.Util.sqlException(Util.java:200)
at org.hsqldb.jdbc.JDBCStatement.fetchResult(JDBCStatement.java:1805)
at org.hsqldb.jdbc.JDBCStatement.executeUpdate(JDBCStatement.java:205)
at coop.data.Connectionsetting.executeupdate(Connectionsetting.java:52)
at coop.data.Connectionsetting.main(Connectionsetting.java:116)
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: AGENCY_MASTER
at org.hsqldb.Error.error(Error.java:76)
at org.hsqldb.SchemaManager.getTable(SchemaManager.java:510)
at org.hsqldb.ParserDQL.readTableName(ParserDQL.java:4367)
at org.hsqldb.ParserDML.compileInsertStatement(ParserDML.java:64)
at org.hsqldb.ParserCommand.compilePart(ParserCommand.java:132)
at org.hsqldb.ParserCommand.compileStatements(ParserCommand.java:83)
at org.hsqldb.Session.executeDirectStatement(Session.java:1037)
at org.hsqldb.Session.execute(Session.java:865)
at org.hsqldb.jdbc.JDBCStatement.fetchResult(JDBCStatement.java:1797)
... 3 more
BUILD SUCCESSFUL (total time: 0 seconds)
Your connection URL looks iffy... try changing:
con=DriverManager.getConnection("jdbc:hsqldb:file"+db_file_name_prefix,"sa", "");
to
con=DriverManager.getConnection("jdbc:hsqldb:file:"+db_file_name_prefix+";ifexists=true","sa", "");
(adding a colon after "file", and appending the ifexists=true flag, as indicated by: http://hsqldb.org/doc/guide/ch04.html
It looks to me like the AGENCY_MASTER table doesn't exist. You're trying to execute an update statement, and it looks like HSQLDB can't find the AGENCY_MASTER table.
You can check whether the table exists with HSQLDB's built-in client/viewer:
java -cp hsqldb.jar org.hsqldb.util.DatabaseManagerSwing