Uploaded image for project: 'Runtime'
  1. Runtime
  2. RUNTIME-138

Excalibur datasource component incompatible avec SqlMap

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Invalid
    • Icon: Major Major
    • 2.8.4
    • 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.

            Unassigned Unassigned
            yabon Sébastien Launay (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: