-
Bug
-
Resolution: Invalid
-
Major
-
1.1.0
-
None
-
None
Le type d'erreur suivant peut arriver en utilisant SqlMap dans le runtime :
Caused by: com.ibatis.common.jdbc.exception.NestedSQLException:
— The error occurred while applying a parameter map.
— Check the Advice.updatePriority-InlineParameterMap.
— Check the parameter mapping for the 'priority' property.
— Cause: java.sql.SQLException: PreparedStatement has been closed. No further operations allowed.
at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeUpdate(GeneralStatement.java:91)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.update(SqlMapExecutorDelegate.java:505)
at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.update(SqlMapSessionImpl.java:90)
at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.update(SqlMapClientImpl.java:67)
... 49 more
Caused by: java.sql.SQLException: PreparedStatement has been closed. No further operations allowed.
at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:1932)
at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:1967)
at com.mysql.jdbc.PreparedStatement.setInt(PreparedStatement.java:509)
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:585)
at org.apache.avalon.excalibur.datasource.AbstractJdbcConnection$ProxiedObject.invoke(AbstractJdbcConnection.java:468)
at $Proxy11.setInt(Unknown Source)
at com.ibatis.sqlmap.engine.type.IntegerTypeHandler.setParameter(IntegerTypeHandler.java:30)
at com.ibatis.sqlmap.engine.mapping.parameter.BasicParameterMap.setParameter(BasicParameterMap.java:165)
at com.ibatis.sqlmap.engine.mapping.parameter.BasicParameterMap.setParameters(BasicParameterMap.java:125)
at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeUpdate(SqlExecutor.java:79)
at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteUpdate(GeneralStatement.java:200)
at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeUpdate(GeneralStatement.java:78)
... 53 more
Ce problème n'arrive que lors que le mode debug de sqlmap est désactivé.
La raison est la suivante : excalibur datasource proxifie les objets PreparedStatement sans redéfinir la méthode equals,
et SqlMap utilise cette méthode implicement via une Map dans l'objet SessionScope. Un statement est alors ajouté à
la map mais il n'est pas possible de savoir si il existe encore dedans, du coup il est fermé mais il peut être récupérer
de nouveau par la suite => PreparedStatement has been closed. No further operations allowed.
Ceci se produit dans une transaction ou le session scope n'est apparement vider qu'à la fin de la transaction.
Pour le moment, passer iBatis SqlMap en debug empêche l'apparition du problème.
Deux solutions sont possibles :
- modifier la classe AbstractJdbcConnection afin de rajouter le bon comportement sur la méthode equals de ProxiedObject ;
- réécrire la DataSource sans proxy car ça servait uniquement à maintenir la compatibilité avec des drivers obsolètes.
- depends on
-
RUNTIME-169 Utiliser un gestionnaire de pool de connexion JDBC contemporain
- Closed