If a query fails, errors thrown by the transaction rollback code
will "hide" the initial query error, making it harder to analyse
the cause of the query failure. In our specific case, the connection
to the PostgreSQL server times out causing the query to fail. The
following rollback fails with "This connection has been closed"
effectively overriding the original error. Extracts from the two
error are below.
Example from com.avaje.ebeaninternal.server.core.DefaultServer,
showing the code in question. Other methods (findMap, findId, etc.)
use the same pattern and would also result in the original query
error being overridden.
@SuppressWarnings("unchecked")
public List findList(Query query, Transaction t) {
SpiOrmQueryRequest request = createQueryRequest(Type.LIST, query, t);
Object result = request.getFromQueryCache();
if (result != null) {
return (List) result;
}
try {
request.initTransIfRequired();
List list = request.findList();
request.endTransIfRequired();
return list;
} catch (RuntimeException ex) {
request.rollbackTransIfRequired();
====> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Errors thrown by this method
means `ex` is never propagated.
throw ex;
}
}
Extract from the rollback exception stack trace:
------------------------------------------------
Caused by: javax.persistence.PersistenceException: org.postgresql.util.PSQLException: This connection has been closed.
at com.avaje.ebeaninternal.server.transaction.JdbcTransaction.rollback(JdbcTransaction.java:646)
at com.avaje.ebeaninternal.server.transaction.JdbcTransaction.rollback(JdbcTransaction.java:627)
at com.avaje.ebeaninternal.server.core.BeanRequest.rollbackTransIfRequired(BeanRequest.java:107)
at com.avaje.ebeaninternal.server.core.DefaultServer.findId(DefaultServer.java:1257)
at com.avaje.ebeaninternal.server.core.DefaultServer.find(DefaultServer.java:1095)
at com.avaje.ebeaninternal.server.core.DefaultServer.find(DefaultServer.java:1082)
at ca.mckesson.liferay.portlets.questionnaire.schema.Model$Finder.byId(Model.java:170)
at ca.mckesson.liferay.portlets.questionnaire.bean.QuestionnairePage.init(QuestionnairePage.java:55)
... 181 more
Caused by: org.postgresql.util.PSQLException: This connection has been closed.
at org.postgresql.jdbc2.AbstractJdbc2Connection.checkClosed(AbstractJdbc2Connection.java:714)
at org.postgresql.jdbc2.AbstractJdbc2Connection.rollback(AbstractJdbc2Connection.java:731)
at org.apache.tomcat.dbcp.dbcp.DelegatingConnection.rollback(DelegatingConnection.java:368)
at org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.rollback(PoolingDataSource.java:323)
at com.avaje.ebeaninternal.server.transaction.JdbcTransaction.rollback(JdbcTransaction.java:639)
... 188 more
Extract from the real exception:
--------------------------------
Caused by: javax.persistence.PersistenceException: Query threw SQLException:An I/O error occured while sending to the backend.
Bind values:[READY]
Query was:
select t0.QID as c0, pgp_sym_decrypt(t0.PROPS,?) as c1, t0.STATUS as c2, t0.CDATE as c3, t0.MDATE as c4
, t1.PID as c5, pgp_sym_decrypt(t1.UID,?) as c6
from QS t0
left outer join PS t1 on t1.PID = t0.PID
where t0.STATUS = ?
at com.avaje.ebeaninternal.server.query.CQuery.createPersistenceException(CQuery.java:834)
at com.avaje.ebeaninternal.server.query.CQuery.createPersistenceException(CQuery.java:814)
at com.avaje.ebeaninternal.server.query.CQueryEngine.findMany(CQueryEngine.java:229)
at com.avaje.ebeaninternal.server.query.DefaultOrmQueryEngine.findMany(DefaultOrmQueryEngine.java:96)
at com.avaje.ebeaninternal.server.core.OrmQueryRequest.findList(OrmQueryRequest.java:291)
at com.avaje.ebeaninternal.server.core.DefaultServer.findList(DefaultServer.java:1521)
at com.avaje.ebeaninternal.server.querydefn.DefaultOrmQuery.findList(DefaultOrmQuery.java:904)
at com.savoirfairelinux.liferay.portlet.bean.SearchPage.search(SearchPage.java:147)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.el.parser.AstValue.invoke(AstValue.java:264)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
... 145 more
Caused by: org.postgresql.util.PSQLException: An I/O error occured while sending to the backend.
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:283)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:273)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at com.avaje.ebeaninternal.server.query.CQuery.prepareBindExecuteQuery(CQuery.java:401)
at com.avaje.ebeaninternal.server.query.CQueryEngine.findMany(CQueryEngine.java:193)
... 158 more
Caused by: java.net.SocketException: Connection timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(Unknown Source)
at com.sun.net.ssl.internal.ssl.InputRecord.read(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:145)
at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:114)
at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:73)
at org.postgresql.core.PGStream.ReceiveChar(PGStream.java:274)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1661)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
... 165 more
Using ebean-2.8.1 via Maven.