You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by "Pawel Veselov (Jira)" <ji...@apache.org> on 2023/03/08 19:44:00 UTC

[jira] [Commented] (OPENJPA-2904) OpenJPAEntityManager.getConnection() may lead to sudden connection closure

    [ https://issues.apache.org/jira/browse/OPENJPA-2904?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17698066#comment-17698066 ] 

Pawel Veselov commented on OPENJPA-2904:
----------------------------------------

Stack traces:
Failure point:
{noformat}
        Caused by: <openjpa-3.1.2-xl4.5-r8cf2e43 fatal general error> org.apache.openjpa.persistence.PersistenceException: Connection has been closed.
                at org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:5297)
                at org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:5257)
                at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:134)
                at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:107)
                at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:59)
                at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.begin(JDBCStoreManager.java:200)
                at org.apache.openjpa.kernel.DelegatingStoreManager.begin(DelegatingStoreManager.java:97)
                at org.apache.openjpa.kernel.BrokerImpl.beginStoreManagerTransaction(BrokerImpl.java:1521)
                at org.apache.openjpa.kernel.BrokerImpl.beginStore(BrokerImpl.java:1505)
                at org.apache.openjpa.kernel.DelegatingBroker.beginStore(DelegatingBroker.java:1188)
                at org.apache.openjpa.persistence.EntityManagerImpl.beginStore(EntityManagerImpl.java:802)
                at com.company.api.impl.db.openjpa.OpenJPAProvider.getRawConnection(OpenJPAProvider.java:39)
                at com.company.db.J2EEDBContext.getConnection(J2EEDBContext.java:316)
                at com.company.db.J2EEDBContext.getConnection(J2EEDBContext.java:306)
                at com.company.db.Database.lambda$apply$3(Database.java:336)
                at com.company.api.lib.util.ApiUtil.reThrow(ApiUtil.java:215)
                at com.company.db.Database.apply(Database.java:334)
                at com.company.db.Database$1.lambda$parse$0(Database.java:546)
                ... 25 more
        Caused by: org.postgresql.util.PSQLException: Connection has been closed.
                at com.company.api.impl.MyPooledConnection$ConnectionHandler.invoke(MyPooledConnection.java:313)
                at com.sun.proxy.$Proxy33.getAutoCommit(Unknown Source)
                at org.apache.openjpa.lib.jdbc.DelegatingConnection.getAutoCommit(DelegatingConnection.java:180)
                at org.apache.openjpa.lib.jdbc.DelegatingConnection.getAutoCommit(DelegatingConnection.java:180)
                at org.apache.openjpa.lib.jdbc.DelegatingConnection.getAutoCommit(DelegatingConnection.java:180)
                at org.apache.openjpa.lib.jdbc.DelegatingConnection.getAutoCommit(DelegatingConnection.java:180)
                at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.begin(JDBCStoreManager.java:196)
{noformat}

Closure point:
{noformat}
        Caused by: java.lang.Exception
                at com.company.api.impl.MyPooledConnection$ConnectionHandler.invoke(MyPooledConnection.java:290)
                at com.sun.proxy.$Proxy33.close(Unknown Source)
                at org.apache.commons.dbcp2.Utils.closeQuietly(Utils.java:124)
                at org.apache.commons.dbcp2.datasources.KeyedCPDSConnectionFactory.validateObject(KeyedCPDSConnectionFactory.java:210)
                at org.apache.commons.dbcp2.datasources.KeyedCPDSConnectionFactory.validateObject(KeyedCPDSConnectionFactory.java:46)
                at org.apache.commons.pool2.impl.GenericKeyedObjectPool.returnObject(GenericKeyedObjectPool.java:1610)
                at org.apache.commons.dbcp2.datasources.KeyedCPDSConnectionFactory.connectionClosed(KeyedCPDSConnectionFactory.java:248)
                at com.company.api.impl.MyPooledConnection.fireConnectionClosed(MyPooledConnection.java:165)
                at com.company.api.impl.MyPooledConnection$ConnectionHandler.invoke(MyPooledConnection.java:303)
                at com.sun.proxy.$Proxy33.close(Unknown Source)
                at org.apache.openjpa.lib.jdbc.DelegatingConnection.close(DelegatingConnection.java:195)
                at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection.close(LoggingConnectionDecorator.java:378)
                at org.apache.openjpa.lib.jdbc.DelegatingConnection.close(DelegatingConnection.java:195)
                at org.apache.openjpa.lib.jdbc.DelegatingConnection.close(DelegatingConnection.java:195)
                at org.apache.openjpa.jdbc.kernel.JDBCStoreManager$RefCountConnection.free(JDBCStoreManager.java:1671)
                at org.apache.openjpa.jdbc.kernel.JDBCStoreManager$RefCountConnection.close(JDBCStoreManager.java:1653)
                at org.apache.openjpa.lib.jdbc.DelegatingConnection.close(DelegatingConnection.java:195)
                at org.apache.openjpa.jdbc.kernel.JDBCStoreManager$ClientConnection.close(JDBCStoreManager.java:1607)
                at org.apache.openjpa.jdbc.kernel.JDBCStoreManager$ClientConnection.finalize(JDBCStoreManager.java:1613)
                at java.lang.System$2.invokeFinalize(System.java:1285)
                at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:102)
                at java.lang.ref.Finalizer.access$100(Finalizer.java:34)
                at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)
{noformat}

> OpenJPAEntityManager.getConnection() may lead to sudden connection closure
> --------------------------------------------------------------------------
>
>                 Key: OPENJPA-2904
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-2904
>             Project: OpenJPA
>          Issue Type: Bug
>    Affects Versions: 3.2.0, 3.2.1, 3.2.2
>            Reporter: Pawel Veselov
>            Priority: Major
>
> (looking at commit 05069dfee, but this code hasn't changed in ages).
> There is a number of methods that chain to {{JDBCStore.getClientConnection()}}
> * {{StoreManager.getClientConnection()}}
> * {{StoreContext.getConnection()}}
> * {{OpenJPAEntityManager.getConnection()}}
> * {{EntityManagerImpl.unwrap()}}
> Callers of these methods typically use the retrieved connection object for an operation, and then let go of it, without any cleanup (as they are supposed to).
> However, {{JDBCStore.getClientConnection()}} implementation creates an instance of {{JDBCStoreManager.ClientConnection}} class every time it's called. These instances, considering how they are used, are therefore short-lived
> However, the implementation {{JDBCStoreManager.ClientConnection}} closes the underlying connection object on finalization.
> This has a relatively high chance of having the underlying connection closed before it's actually properly released.
> I don't necessarily know what the right fix for this is, but locally I will just make ClientConnection a field of RefCountConnection, it's a lightweight class so I can create it right away, then I'll have {{JDBCStore.getClientConnection()}} just return that. There may be some gotchas there, but I just need a quick solution because this suddenly became a persistent problem.
> I've overridden the pooled connection implementation to try to trace the connection random connection closure that we are experiencing under some random scenarios, and I attached an exception to the connection object when it's closed, and I see when an attempt to use a closed connection happens - it's because the GC closed it through {{JDBCStoreManager.ClientConnection}}.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)