I'm working on a project in whose database I need to initialize a session variable. If I work directly with sql, the initialization is done with SET statement
set local app.user_id to "0000";
I try to initialize it with Connection#setClientInfo() but failed
try(Connection connection = getDataSource().getConnection()) {
boolean isAutoCommit = connection.getAutoCommit();
try {
Properties properties = new Properties();
properties.put("app.user_id", "0000");
connection.setAutoCommit(false);
connection.setClientInfo(properties);
String query = "insert into positions (name, description) values (?, ?)";
try(PreparedStatement statement = connection.prepareStatement(query)) {
statement.setString(1, position.getName());
statement.setString(2, position.getDescription());
statement.executeUpdate();
}
connection.commit();
}
catch (SQLException e) {
e.printStackTrace();
connection.rollback();
}
finally {
connection.setAutoCommit(isAutoCommit);
}
}
I get PSQLException (insert query is dependent on parameter and it does not pass)
org.postgresql.util.PSQLException: ERROR: unrecognized configuration parameter "app.user_id"
If I use PreparedStatement I get PSQLException with message ERROR: syntax error at or near "$1"
try(Connection connection = getDataSource().getConnection()) {
boolean isAutoCommit = connection.getAutoCommit();
try {
connection.setAutoCommit(false);
try(PreparedStatement statement = connection.prepareStatement("set local app.user_id to ?")) {
statement.setString(1, "0000");
statement.execute();
}
String query = "insert into positions (name, description) values (?, ?)";
try(PreparedStatement statement = connection.prepareStatement(query)) {
statement.setString(1, position.getName());
statement.setString(2, position.getDescription());
statement.executeUpdate();
}
connection.commit();
}
catch (SQLException e) {
e.printStackTrace();
connection.rollback();
}
finally {
connection.setAutoCommit(isAutoCommit);
}
}
The only way to go through is by directly executing the query with fixed values. But in doing so, I am forced to use a concatenation to build the query. And I do not want to do it.
try(Connection connection = getDataSource().getConnection()) {
boolean isAutoCommit = connection.getAutoCommit();
try {
connection.setAutoCommit(false);
try(Statement statement = connection.createStatement()) {
statement.execute("set local app.user_id to 0000");
}
String query = "insert into positions (name, description) values (?, ?)";
try(PreparedStatement statement = connection.prepareStatement(query)) {
statement.setString(1, position.getName());
statement.setString(2, position.getDescription());
statement.executeUpdate();
}
connection.commit();
}
catch (SQLException e) {
e.printStackTrace();
connection.rollback();
}
finally {
connection.setAutoCommit(isAutoCommit);
}
}
What is the right way to initialize such parameters?
I use PostgreSQL 11, JDBC 4.2 (with driver 42.2.5) and DBCP 2.5
Edit
I did it by calling set_config.
try(PreparedStatement statement = connection.prepareStatement("select set_config(?, ?, true)")) {
statement.setString(1, "app.user_id");
statement.setString(2, "0000");
statement.execute();
}
But the question remains. How to call SET in JDBC
I think you need to do this on the DataSource not the Connection.
In postgresql the only way I know of would be to downconvert. Something like:
DataSource myDS = getDataSource();
if (DataSource instanceof BaseDataSource.class) {
BaseDataSource pgDS = (BaseDataSource) myDS; // expose setProperty method
pgDS.setProperty("app.user_id", "0000");
}
where you place this in your application obviously depends upon many details not presented in your question.
Related
I just started learning about MySQL and I am now trying to learn prepared statements. When I uses them, I get this error java.sql.SQLSyntaxErrorException. Can someone tell me where am I getting the syntax wrong? Thanks. Here is my code:
public class DBConnector {
private Statement statement;
private ResultSet result;
private PreparedStatement preparedStatement;
public void createDB() {
try {
sql = "CREATE DATABASE IF NOT EXISTS ?";
tableName = "test_name";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, tableName);
int myResult = preparedStatement.executeUpdate();
if(myResult == 1){
System.out.println("Database successfully created.");
}else{
System.out.println("Database with that name already exists. Please try again with different name.");
createDB();
}
}catch (SQLException e) {
System.out.println("Database creation failed.");
e.printStackTrace();
}
}
}
We can't bind Database names in Query parameters.
Statement stmt=con.createStatement();
int rs=stmt.executeUpdate("CREATE DATABASE dbname");
Try in this way, Database will create.
I have DAO class with methods getting and sending data.
I'm catching Exceptions inside SQL requests, so I need to declare connection variables outside of try parenthesis.
every method looks lookes like this:
public Role getRole(int roleId) {
Connection connection = null;
ResultSet rs = null;
PreparedStatement statement = null;
Role role = null;
try {
connection = dataSource.getConnection();
statement = connection.prepareStatement("select ROLE_ID, ROLE_TEXT from ROLES WHERE ROLE_ID = :1");
statement.setInt(1, roleId);
rs = statement.executeQuery();
rs.next();
role = roleMapper.mapRow(rs, 1);
} catch (SQLException e) {
} finally {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(statement);
JdbcUtils.closeConnection(connection);
return role;
}
}
But there's problem. Finbugs giving me an error, saying:
Load of known null value in DAO.getRole
and
may fail to clean up java.sql.Statement
So what should I do to avoid that?
The getRole can return null.
Furthermore:
if (rs.next()) {
role = roleMapper.mapRow(rs, 1);
}
I prefer another notation. And the error solution unfortunately consists of either letting getRole throw an exception (best) or letting return an Optional<Role>
//public Role getRole(int roleId) throws SQLException {
public Optional<Role> getRole(int roleId) {
try (Connection connection = dataSource.getConnection();
PreparedStatement statement =
connection.prepareStatement(
"select ROLE_ID, ROLE_TEXT from ROLES WHERE ROLE_ID = :1")) {
statement.setInt(1, roleId);
try (ResultSet rs = statement.executeQuery()) {
if (rs.next()) {
return roleMapper.mapRow(rs, 1);
}
}
} catch (SQLException e) { //
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "ID: " + roleId, e); //
}
return Optional.empty(); //
}
I'm attempting to enter a set of values to tables reservation,resdetails using database transactions. There are no exceptions thrown, but values are not being entered in to DB.Here i've used utilised java.sql.PreparedStatement.
public boolean addReservation(Reservation res, ArrayList<ReservationDetails> resdetlist) throws Exception {
connection = DBConnection.getDBConnection();
try {
System.out.println("A");
connection.setAutoCommit(false);
PreparedStatement ps1 = connection.prepareStatement("insert into reservation values(?,?,?,?)");
ps1.setString(1, res.getResid());
ps1.setBoolean(2, res.isCheckin_status());
ps1.setString(3, res.getRes_from());
ps1.setString(4, res.getRes_till());
int addedres = ps1.executeUpdate();
System.out.println("addres:" + addedres);
System.out.println("B");
if (addedres > 0) {
for (ReservationDetails resdet : resdetlist) {
//int addedresdet = addReservationDetails(resdet);
PreparedStatement ps2 = connection.prepareStatement("insert into resdetails values(?,?,?,?,?,?)");
ps2.setString(1, resdet.getResid());
ps2.setString(2, resdet.getNic());
ps2.setString(3, resdet.getPayment_id());
ps2.setString(4, resdet.getRoom_no());
ps2.setString(5, resdet.getType_of_accomodation());
ps2.setString(6, resdet.getDate_of_reservation());
int addedresdet = ps2.executeUpdate();
System.out.println("addedresdet:" + addedresdet);
System.out.println("C");
if (addedresdet <= 0) {
System.out.println("D");
connection.rollback();
return false;
}
}
} else {
System.out.println("E");
connection.rollback();
return false;
}
connection.commit();
} catch (Exception ex) {
// ex.printStackTrace();
connection.rollback();
} finally {
connection.setAutoCommit(true);
System.out.println("F");
}
return true;
}
If executeUpdate() returns <= 0 then nothing changed in the database, therefore there's no need to rollback the transaction. Also, if a problem occurred while inserting the entry (eg. a constraint violation, etc) then the executeUpdate() throws a SQLException. I would change you code to:
try {
connection.setAutoCommit(false);
PreparedStatement ps1 = ...
...
ps1.executeUpdate();
for (ReservationDetails resdet : resdetlist) {
PreparedStatement ps2 = ...
...
ps2.executeUpdate();
}
connection.commit();
} catch (SQLException e) {
connection.rollback();
}
Also, don't forget to call close() on the PreparedStatements after you use them, and on the connection object at the end of the method.
I have a problem inserting data into MYSQL database. Using code below I get an error:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?,?)' at line 1
CODE:
public void signUpUser(Connection conn, String userName, String password) {
String queryString = "INSERT INTO USERS (USER_ALIAS, USER_PASS) VALUES (?,?)";
try {
preparedStatement = (PreparedStatement) conn.prepareStatement(queryString);
preparedStatement.setString(1, userName);
preparedStatement.setString(2, password);
preparedStatement.executeUpdate(queryString);
} catch (SQLException e) {
e.printStackTrace();
}
}
But with this code the insert works normally:
public void signUpUser(Connection conn, String userName, String password) {
String queryString = "INSERT INTO USERS (USER_ALIAS, USER_PASS) VALUES ('"+userName+"', '"+password+"')";
try {
preparedStatement = (PreparedStatement) conn.prepareStatement(queryString);
preparedStatement.executeUpdate(queryString);
} catch (SQLException e) {
e.printStackTrace();
}
}
I want to know why does it throws error while using first part of code
Thank you in advance!
You are trying to execute update with the string although you have already created the statement.
You have to use:
preparedStatement.executeUpdate();
Hi I have this method below which should insert values into my database. However I am getting a Null Pointer Exception on the PreparedStatement line
public void insertReservation(String name, String phone, int size, String date, String time, String additionalRequirements, String memberID, String themeID) throws SQLException, ClassNotFoundException {
try {
String strQuery = "INSERT INTO reservation VALUES (?, ? ,?, TO_DATE(?, 'dd-MMM-yy'), ?, ?, ?, ?)";
PreparedStatement stmt = conn.prepareStatement(strQuery);/
stmt.setString(1, name);
stmt.setString(2, phone);
stmt.setInt(3, size);
stmt.setString(4, date);
stmt.setString(5, time);
stmt.setString(6, additionalRequirements);
stmt.setString(7, memberID);
stmt.setString(8, themeID);
results = stmt.executeQuery();
} catch (Exception e) {
e.printStackTrace();
}//end try
}
Am I inserting this correctly into my database? I am not sure why I am getting this null pointer exeception error.
conn is null, print its value.
Don't know but try this
String strQuery = "insert into reservation(ColumnName1, ColumnName2 ,ColumnName3,) values(?,?,?)";
and at the end it will be only execute();
like this stmt.execute();
executeQuery(); statement works with select query Only
Secondly have you described conn value in constructor or method in which ever class you are using the query if you have than assign it like this conn= SqlConnection.ConnecrDb();
below is the SqlConnection Seperate class i have created
public class SqlConnection {
Connection conn=null;
public static Connection ConnecrDb(){
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn= DriverManager.getConnection("jdbc:odbc:Test","","");
return conn;
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null, e);
return null;
}
}
}
Hope it will help you