Giving error at line 12 "This method must return a result of type Boolean".
I have written my code in try catch block. If a move the resultset operation below the catch block then the error appears on resultset object.
Where am I wrong, Please answer me. Thank you.
public class LoginService {
public Boolean verifyLogin(LoginModel loginModel) { // In this line it is
// giving error
DbConnection dbConnection = new DbConnection();
ResultSet rs;
try {
Connection con = dbConnection.getConnection();
System.out.println("Connection Established");
String query = "select * from login where tenantid=? and userid=? and password=?";
PreparedStatement ps = con.prepareStatement(query);
ps.setInt(1, loginModel.getTenantid());
ps.setString(2, loginModel.getUserid());
ps.setString(3, loginModel.getPassword());
rs = ps.executeQuery();
if (rs.next()) {
System.out.println("User exists !!");
return true;
} else {
System.out.println("User does not exists !!");
return false;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
When your code catches an exception you are simply printing the stacktrace and then allowing the function to continue.
However, after the catch blocks, you have no return statement, which is what the complaint is.
As others have mentioned, you're missing a return statement either in the catch blocks or after the catch blocks. Here's my boiler plate example of a function that returns a boolean:
bool foo()
{
bool result = false;
//do stuff, and set result to true at some point
return result;
}
This pattern is beneficial because it helps reduce the number of returns in your functions. There are some coding styles out there that won't allow more than 2 return statements in a function, for example.
Here it is applied to your function:
public Boolean verifyLogin(LoginModel loginModel) { // In this line it is
// giving error
Boolean result = false;
DbConnection dbConnection = new DbConnection();
ResultSet rs;
try {
Connection con = dbConnection.getConnection();
System.out.println("Connection Established");
String query = "select * from login where tenantid=? and userid=? and password=?";
PreparedStatement ps = con.prepareStatement(query);
ps.setInt(1, loginModel.getTenantid());
ps.setString(2, loginModel.getUserid());
ps.setString(3, loginModel.getPassword());
rs = ps.executeQuery();
if (rs.next()) {
System.out.println("User exists !!");
result = true; //--------------------This line changed!
} else {
System.out.println("User does not exists !!");
result = false; //-------------------This line changed!
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
You should return in catch blocks too. Or in finally block.
You need to add a return statement after your catch block.
Your method may throw an exception, in this case, the code that will be executed will be in the catch clauses.
Add a finally clause after the catch's with the desired value for when this happens.
The problem is that if an exception occurs, nothing is returned. I would suggest adding
return false;
to all of your catch blocks
Related
I try to insert a row to the database, but it doesn't appear in the table after running:
This is the main class:
public class Tester {
public static void main(String[] args) {
CouponsDbDao coupDbDao = new CouponsDbDao();
Coupon coupon = new Coupon(1, 0, Category.Food, null, null, null, null, 25, 0, null);
coupDbDao.addCoupon(coupon);
}
}
And this is the method:
public class CouponsDbDao {
public void addCoupon(Coupon coupon) {
try {
Connection connection = JdbcUtils.getConnection();
String sqlStatement = "insert into coupons (COMPANY_ID,CATEGORY_ID,TITLE,DESCRIPTION,START_DATE,END_DATE,AMOUNT,PRICE,IMAGE) values(?,?,?,?,?,?,?,?,?)";
PreparedStatement statement = connection.prepareStatement(sqlStatement);
statement.setInt(1, coupon.getCompanyId());
statement.setObject(2, coupon.getCategory());
statement.setString(3, coupon.getTitle());
statement.setString(4, coupon.getDescription());
statement.setDate(5, coupon.getStartDate());
statement.setDate(6, coupon.getEndDate());
statement.setInt(7, coupon.getAmount());
statement.setDouble(8, coupon.getPrice());
statement.setString(9, coupon.getImage());
} catch (Exception e) {
e.printStackTrace();
}
}
You need to execute the statement after setting values. Additionally, you need to close the connection created, the preparedstatement etc in a finally block.
public class CouponsDbDao {
Connection connection = null;
PreparedStatement statement = null;
public void addCoupon(Coupon coupon) {
try {
connection= JdbcUtils.getConnection();
String sqlStatement = "insert into coupons (COMPANY_ID,CATEGORY_ID,TITLE,DESCRIPTION,START_DATE,END_DATE,AMOUNT,PRICE,IMAGE) values(?,?,?,?,?,?,?,?,?)";
statement = connection.prepareStatement(sqlStatement);
statement.setInt(1, coupon.getCompanyId());
statement.setObject(2, coupon.getCategory());
statement.setString(3, coupon.getTitle());
statement.setString(4, coupon.getDescription());
statement.setDate(5, coupon.getStartDate());
statement.setDate(6, coupon.getEndDate());
statement.setInt(7, coupon.getAmount());
statement.setDouble(8, coupon.getPrice());
statement.setString(9, coupon.getImage());
statement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
finally{
if (statement != null) {
try {
statement.close();
} catch (SQLException e) { /* print here */}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) { /* print here */}
}
}
}
As told by others you need to call executeUpdate to really perform the query:
Executes the SQL statement in this PreparedStatement object, which must be an SQL Data Manipulation Language (DML) statement, such as INSERT, UPDATE or DELETE
I suggest you also to use the try with resources:
The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
This has been introduced in java 7 and let you eliminate the finally boiler plate code as follow:
// ORIGINAL CODE
Connection connection = ...
try {
connection = JdbcUtils.getConnection();
...
statement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (statement != null) {
try {
statement.close();
} catch (SQLException e) { /* print here */}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) { /* print here */}
}
}
becomes:
// USING try with resources
try (Connection connection = JdbcUtils.getConnection()) {
...
statement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} // NO need of the finally block because connection is AutoCloseable
You need to execute update for statement, like:
statement.executeUpdate();
I am trying to run a PLSQL script which I have as a string value with the following method.
I first create the procedure
then I create a callStatement to call it
and finally I add some parameters
I get the error message:
ORA-06575: Package or function PROCEDURE_NAME is in an invalid state
Any ideas what I can do about that?
This is the code:
public IResult createAndExecuteCallable(String queryText, String procedureName, Object[] parameter) {
IResult result = new Result();
String procedure = "create procedure "+procedureName+"("+queryText+")";
Connection connection = this.getDatabaseConnection().getConnection();
try {
connection.setAutoCommit(true);
Statement stmt = connection.createStatement();
stmt.executeUpdate(procedure);
CallableStatement statement = connection.prepareCall("call "+procedureName+"()");
commonPreparedStatment(statement,parameter);
try {
statement.executeUpdate();
} catch(SQLException se){
result = new Result(se);
} finally {statement.close();}
} catch(Exception e){
result = new Result(e);
} finally {
closeConnection(connection);
}
return result;
}
Thanks to the comments and some other help I found the solution. Here is the new middle part of the code, now including compilation:
connection.setAutoCommit(true);
PreparedStatement createStatement = connection.prepareStatement(queryCreateText);
PreparedStatement compileStatement = connection.prepareStatement(queryCompileText);
CallableStatement statement = connection.prepareCall(queryCallText);
commonPreparedStatment(statement, parameter);
try {
createStatement.executeUpdate();
log.info("create ok");
} catch (SQLException ignored) {
log.info(ignored.getMessage());
} finally {
log.info(queryCompileText);
createStatement.close();
}
try {
compileStatement.executeUpdate();
log.info("compile ok");
} catch (SQLException ignoredToo) {
log.info(ignoredToo.getMessage());
} finally {
compileStatement.close();
}
try {
statement.executeUpdate();
log.info("execute ok");
} catch (SQLException se) {
result = new Result(se);
} finally {
statement.close();
}
One additional obstacle was the file content of the plsql code. It contained line breaks and Oracle did not accept them. So I had to remove them before creating the procedure in Oracle:
queryCreateText = queryCreateText.replace("\r\n", " ");
I'm trying to figure out how to rollback commits from multiple methods. I want to do something like the following (editing for brevity)
public void testMultipleMethodRollback() throws DatabaseException {
Connection conn = connect();
fakeMethodRollback1();
fakeMethodRollback2();
try {
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
and currently all my methods are formatted like this
public void fakeMethodRollback1() throws DatabaseException {
Connection con = connect();
PreparedStatement ps = null;
ResultSet rs = null;
// insert some queries
try {
String query = "some query";
ps = conn.prepareStatement(query);
ps.executeUpdate(query);
query = "some query";
ps = conn.prepareStatement(query);
ps.executeUpdate(query);
con.commit();
} catch (SQLException e) {
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
throw new DatabaseException(e);
} finally {
close(rs, ps, conn);
}
}
because I want to be able to use the other methods independently, how can I do a rollback where if one method fails, the others will roll back? I fear I have my whole class setup wrong or at least wrong enough that this can't be accomplished without major work. I can't change the methods to return a connection, because half of my methods are get methods, which are already returning other data. Any ideas?
There are many steps involved in executing one SQL statement in Java:
Create connection
Create statement
Execute statement, create resultset
Close resultset
Close statement
Close connection
At each of these steps SQLException can be thrown. If we to handle all exception and release all the resources correctly, the code will will look like this with 4 levels of TRY stacked on the top of each other.
try {
Connection connection = dataSource.getConnection();
try {
PreparedStatement statement = connection.prepareStatement("SELECT 1 FROM myTable");
try {
ResultSet result = statement.executeQuery();
try {
if (result.next()) {
Integer theOne = result.getInt(1);
}
}
finally {
result.close();
}
}
finally {
statement.close();
}
}
finally {
connection.close();
}
}
catch (SQLException e) {
// Handle exception
}
Can you propose a better (shorter) way to execute a statement while still release all the consumed resources?
If you are using Java 7, the try with resources statement will shorten this quite a bit, and make it more maintainable:
try (Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement(queryString); ResultSet rs = ps.execute()) {
} catch (SQLException e) {
//Log the error somehow
}
Note that closing the connection closes all associated Statements and ResultSets.
Check out Apache Commons DbUtils, and in particular the closeQuietly() method. It will handle the connection/statement/result set closing correctly, including the cases where one or more are null.
An alternative is Spring JdbcTemplate, which abstracts a lot of work away from you, and you handle your database queries in a much more functional fashion. You simply provide a class as a callback to be called on for every row of a ResultSet. It'll handle iteration, exception handling and the correct closing of resources.
I create a utility class with static methods I can call:
package persistence;
// add imports.
public final class DatabaseUtils {
// similar for the others Connection and Statement
public static void close(ResultSet rs) {
try {
if (rs != null) {
rs.close();
}
} catch (Exception e) {
LOGGER.error("Failed to close ResultSet", e);
}
}
}
So your code would be:
Integer theOne = null;
Connection connection = null;
PreparedStatement statment = null;
ResultSet result = null;
try {
connection = dataSource.getConnection();
statement = connection.prepareStatement("SELECT 1 FROM myTable");
result = statement.executeQuery();
while (result.next()) {
theOne = result.getInt(1);
}
} catch (SQLException e) {
// do something
} finally {
DatabaseUtils.close(result);
DatabaseUtils.close(statement);
DatabaseUtils.close(connection);
}
return theOne;
I'd recommend instantiating the Connection outside this method and passing it in. You can handle transactions better that way.
Connection connection = null;
PreparedStatement statement = null;
ResultSet result = null;
try {
connection = dataSource.getConnection();
statement = connection.prepareStatement("SELECT 1 FROM myTable");
result = statement.executeQuery();
if (result.next()) {
Integer theOne = result.getInt(1);
}
}
catch (SQLException e) { /* log error */ }
finally {
if (result != null) try { result.close(); } catch (Exception e) {/*log error or ignore*/}
if (statement != null) try { statement.close(); } catch (Exception e) {/*log error or ignore*/}
if (connection != null) try { connection.close(); } catch (Exception e) {/*log error or ignore*/}
}
Just close the Connection, this releases all resources*. You don't need to close Statement and ResultSet.
*just make sure you don't have any active transactions.
Your code can be shortened and written in this way...
Connection connection = dataSource.getConnection();
PreparedStatement statement = null;
ResultSet result = null;
try {
statement= connection.prepareStatement("SELECT 1 FROM myTable");
result = statement.executeQuery();
if (result.next()) {
Integer theOne = result.getInt(1);
}
} catch (SQLException e) {
// Handle exception
} finally {
if(result != null) result.close();
if(statement != null) statement.close();
if(connection != null) connection.close();
}
I need a good way to close SQLIte connections in Java. After a few suggestion by other users I decided to add to my code a finally block to be sure that closing operation are always executed.
public static boolean executeQuery(String query)
{
Connection conn = null;
Statement stmt = null;
try
{
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection(Global.dbPath);
stmt = conn.createStatement();
stmt.execute(query);
return true;
}
catch(ClassNotFoundException e)
{
System.out.println(e);
return false;
}
catch(SQLException e)
{
System.out.println(e);
return false;
}
finally
{
try
{
stmt.close();
conn.close();
return true;
}
catch (SQLException ex)
{
System.out.println ("Errore closing connections");
return false;
}
}
}
I'm not sure that this is the best solution.
How can I optimize this for readability?
A few comments; nutshells:
Separate the SQL exceptions from the reflection exception.
Are your SQL exceptions recoverable? If not, throw an app-specific RuntimeException.
Wrap up the connection and statement close exceptions in a utility method, yours or a 3rd party's.
Don't short-change exception handling; dump the stack trace.
This leads to the following:
public static boolean executeQuery(String query) {
try {
Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException e) {
throw new DbException("Could not find JDBC driver", e);
}
Connection conn = null;
Statement stmt = null;
try {
conn = DriverManager.getConnection(Global.dbPath);
stmt = conn.createStatement();
stmt.execute(query);
return true;
} catch(SQLException e) {
throw new DbException("Exception during statement execution", e);
} finally {
DbUtils.closeQuietly(conn);
DbUtils.closeQuietly(stmt);
}
}
(I'm using Apache Commons' DbUtils for its closeQuietly, it checks for null (yours didn't). Your own version might throw an app-specific exception as I do here with DbException. This wraps up all your DB-related exceptions into a single exception class, which may or may not be what you need.
If you want to make sure a command is executed you have to put it alone into a try catch block:
try {
stmt.close();
}
catch (Exception ex) {
}
try {
conn.close();
}
catch (Exception ex) {
System.out.println ("Error closing connections");
return false;
}