3

I use weblogic application server and oracle database. I use jdbc for communicating with the oracle database. I get the connection from weblogic datasource and insert a record to the table. The problem is that when I want to close the connection (after inserting to the database) I'll face with an exception (Connection has already been closed) .This is my code:

private Connection getConnection() {
    try {
        Context context = new InitialContext();
        DataSource datasource = (DataSource) context.lookup("jdbc/datasource-uat");
        Connection connection = datasource.getConnection();
        connection.setAutoCommit(false);
        return connection;
    } catch (Throwable throwable) {
        throwable.printStackTrace();
        return null;
    }
}


    public void persist(Long id) {
    Connection connection = null;
    try {
        connection = getConnection();
        PreparedStatement preparedStatement;
        ResultSet resultSet = null;
        if (id == 0L) {
            synchronized (this) {
                preparedStatement = connection.prepareStatement("SELECT MY_BEAN_SEQ.NEXTVAL FROM DUAL");
                resultSet = preparedStatement.executeQuery();
            }
            resultSet.next();
            id = resultSet.getLong("NEXTVAL");
        }

        preparedStatement = connection.prepareStatement("INSERT INTO MY_BEAN (ID) VALUES (?)");
        preparedStatement.setLong(1, id);
        preparedStatement.executeUpdate();
        connection.commit();
        if (resultSet != null) {
            resultSet.close();
        }
        preparedStatement.close();


    } catch (Throwable throwable) {
        throwable.printStackTrace();
    }

    finally {
        closeConnection(connection);
    }
}


private void closeConnection(Connection connection) {
    if (connection != null)
        try {
            connection.close();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
}

But connection.close statement throws an exception:

java.sql.SQLException: Connection has already been closed.
at weblogic.jdbc.wrapper.PoolConnection.checkConnection(PoolConnection.java:62)
at weblogic.jdbc.wrapper.Connection.preInvocationHandler(Connection.java:100)
at weblogic.jdbc.wrapper.Connection.getMetaData(Connection.java:476)
at com.DataAccess.closeConnection(DataAccess.java:61)
at com.DataAccess.persist(DataAccess.java:289)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:188)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:104)
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:204)
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:101)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:94)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:249)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:248)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:222)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:153)
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:181)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:289)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:209)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:265)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:301)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:184)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3732)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3696)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2273)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2179)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1490)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)

I tried to avoid connection.close statement (because I taught that connection is closed automatically!! but after a while all of the connections were opened and an exception was thrown due to that)

Kian
  • 211
  • 1
  • 3
  • 17
  • SO is full of questions covering this error message? Did you do any research before posting? – Tim Biegeleisen Jul 16 '18 at 06:54
  • @Tim Biegeleisen: Did you just remove your answer? Anyway, in my case I haven't any idea what is reason of this exception. Do you have? – Kian Jul 16 '18 at 07:01
  • add a check into closeConnection method if the connection is also still open, something like `if (connection != null && connection.isOpen())` (I don't remember the exact syntax) – Leviand Jul 16 '18 at 07:04
  • @Leviand Scroll down in his code. He is already doing this. – Tim Biegeleisen Jul 16 '18 at 07:05
  • @TimBiegeleisen no man, he's only checking if is != null – Leviand Jul 16 '18 at 07:05
  • @Leviand where is connection closed? My whole code is that and I don't have any idea where connection is closed. – Kian Jul 16 '18 at 07:08
  • @Mohammad have you created a test that launches only 1 time this method? Possibilities could be many (calling concurrently this method, connection's xml setted for autoclose connections, etc etc)... let's start from a test – Leviand Jul 16 '18 at 07:12
  • @Leviand Yes, I did. The exception was thrown – Kian Jul 16 '18 at 07:13
  • please add to your question the code of **datasource-uat** – Leviand Jul 16 '18 at 07:22
  • The stacktrace doesn't seem to match the code. According to the stacktrace, `closeConnection` calls `getMetaData()`, while according to the code it class `close()`. Make sure you're posting the right code. – Mark Rotteveel Jul 16 '18 at 07:35
  • BTW: You could simplify your code a lot by using try-with-resources. – Mark Rotteveel Jul 16 '18 at 07:37
  • @Leviand datasource-uat has been set on weblogic. Id does not consist any special setting. You can see that in: http://tinypic.com/r/28qsu2p/9 – Kian Jul 16 '18 at 07:56
  • @MarkRotteveel Be sure that it's the right code. I don't call getMetaData(), and I use jdk6 – Kian Jul 16 '18 at 07:58
  • Then you are executing different code than you think you are, because that stacktrace doesn't lie that `com.DataAccess.closeConnection` (line 61) is calling `getMetaData` on the weblogic JDBC connection wrapper. – Mark Rotteveel Jul 16 '18 at 08:00
  • @MarkRotteveel i don't call getMetaData, but weblogic does – Kian Jul 16 '18 at 08:28
  • Be aware that this will happen if you're setting "setRemoveAbandoned(true)" on your datasource. Any transaction that goes beyond the timeout you specify in that case will have been closed by the time it actually completes. – Alkanshel Aug 01 '18 at 03:39

1 Answers1

1

Try using a try-with-resources Statement to "automatically" close your connection.

Similar to this