user2890683
user2890683

Reputation: 411

No operations allowed after statement closed

I am getting the Exception with the signature No operations allowed after statement closed. inside my Java code where I am trying to insert values into the database. The error signature says that my Statement object gets closed and I am trying to use it again in my code , but what I am struggling to understand is why is this happening as I am not closing any connections anywhere in my code.

Here is the Java code.

public class DataBaseAccessUtils {

    private static String jdbcUrl = 
            AppConfig.findMap("BXRequestTracker").get("jdbcUrl").toString();
    private static Connection connection = null;
    private static Statement statement = null;

    public static void insertHostname(String hostname, String rid, String fleet, String locale)
    {
        locale.toUpperCase();
        String sql = "UPDATE " + locale + "REQUESTTRACKER SET " + fleet 
                + "='" + hostname + "' WHERE RID='" + rid + "'";
        try {
            statement.execute(sql);
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static Statement connectToDatabase() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(DataBaseAccessUtils.jdbcUrl);
            statement = connection.createStatement();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return statement;
    }

Also I have observed that the error does not come when there is a single threaded execution , it comes up when multiple threads are trying to update the database simultaneously.

Upvotes: 6

Views: 41364

Answers (3)

faizan ahmad
faizan ahmad

Reputation: 41

It may be because of you are using the same prepared statement for two different methods and you close(pst.close()) the statement in one method and still try to use same statement in another method.

To solve this, get a new connection in a code block you are facing this error and then use statement.

One thing more if you are using same statement for two different methods and if you do not close statement in any method then you may get this error:

Parameter index out of range (2 > number of parameters, which is 1).

because of same statement . So try to get separate connection and statement for block of code and then close the connection and statement.

Upvotes: 1

Braj
Braj

Reputation: 46841

Create a Utility class for connection management to manage it at single point in whole application.

Don't load the DataSource every time you need a new connection.

Sample code:

public class ConnectionUtil {

    private DataSource dataSource;

    private static ConnectionUtil instance = new ConnectionUtil();

    private ConnectionUtil() {
        try {
            Context initContext = new InitialContext();
            dataSource = (DataSource) initContext.lookup("JNDI_LOOKUP_NAME");
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    public static ConnectionUtil getInstance() {
        return instance;
    }

    public Connection getConnection() throws SQLException {
        Connection connection = dataSource.getConnection();
        return connection;
    }

    public void close(Connection connection) throws SQLException {
        if (connection != null && !connection.isClosed()) {
            connection.close();
        }
        connection = null;
    }

}

Always close the connection and handle it in try-catch-finally

        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            conn = ConnectionUtil.getInstance().getConnection();

            ...
        } finally {
            if (rs != null) {
                rs.close();
            }
            if (stmt != null) {
                stmt.close();
            }
            if (conn != null) {
                ConnectionUtil.getInstance().close(conn);
            }
        }

Upvotes: 5

keyser
keyser

Reputation: 19189

statement is static, so it's shared among instances (and threads). One thread is probably trying to use that object after another one has closed it.

It is generally a bad idea to share database connections and statements between threads since JDBC does not require connections to be thread-safe.

Upvotes: 2

Related Questions