It was indeed a bug (at least with my definition of bug...)

To recapitulate (again) : insertion of strings (as varchar2) end up as null
in the DB.

The Microsoft driver is not affected by this, but for us it is not an option
(we need the extra
features of the oracle driver).

The fix involves a change in the class :

  IBatisNet.DataMapper.MappedStatements.MappedStatement

// FIX BEGIN (line 225)
 
if(typeof(command).FullName.Equals("Oracle.DataAccess.Client.OracleCommand")
&&
         !sqlParameter.DbType.Equals(System.Data.DbType.String))
                                    ((IDbDataParameter)parameterCopy).Size =
((IDbDataParameter)sqlParameter).Size;
// END FIX

A few non public fields of oracle's connection differ when
IDbDataParameter.Size is set

- Not good (when Size set to 0) :
                m_maxSize       0       int
                m_modified      true    bool
                m_precision     0       byte

- Good (when Size set never set) :
                m_maxSize       -1      int
                m_modified      false   bool
                m_precision     100     byte


 My conclusion is that no one else is using ibatis + oracle's odp.net 
together, and your test suite probably doesn't include the combination,
Which leaves me a bit worried of using iBatis for our project.

 On the other hand, I like the fact that ibatis leaves full control 
of the sql/stored procs, but using an untested driver is risky
(this is a commercial project).

 So, is this driver supported, or will it be in the very
Near future ? (i.e. will the odp.net driver be 
Tested as part of the nunit test suite ) ?


                private void ApplyParameterMap
                        ( IDalSession session, IDbCommand command,
                        RequestScope request, object parameterObject )
                {
                        ArrayList properties =
request.PreparedStatement.DbParametersName;
                        ArrayList parameters =
request.PreparedStatement.DbParameters;

                        for ( int i = 0; i < properties.Count; ++i )
                        {
                                IDataParameter sqlParameter =
(IDataParameter)parameters[i];
                                string propertyName = (string)properties[i];

                                if (command.CommandType == CommandType.Text)
                                {
                                        if ( propertyName != "value" ) //
Inline Parameters && Parameters via ParameterMap
                                        {
                                                ParameterProperty property =
request.ParameterMap.GetProperty(i);

                                                sqlParameter.Value =
request.ParameterMap.GetValueOfProperty(parameterObject,
        
property.PropertyName);
                                        }
                                        else // 'value' parameter
                                        {
                                                sqlParameter.Value =
parameterObject;
                                        }
                                }
                                else // CommandType.StoredProcedure
                                {
                                        // A store procedure must always use
a ParameterMap 
                                        // to indicate the mapping order of
the properties to the columns
                                        if (request.ParameterMap == null) //
Inline Parameters
                                        {
                                                throw new
DataMapperException("A procedure statement tag must alway have a
parameterMap attribut, which is not the case for the procedure
'"+_statement.Id+"'."); 
                                        }
                                        else // Parameters via ParameterMap
                                        {
                                                ParameterProperty property =
request.ParameterMap.GetProperty(i);

                                                if
(property.DirectionAttribut.Length == 0)
                                                {
                                                        property.Direction =
sqlParameter.Direction;
                                                }

//                                              IDbDataParameter
dataParameter = (IDbDataParameter)parameters[i];
//                                              property.Precision =
dataParameter.Precision;
//                                              property.Scale =
dataParameter.Scale;
//                                              property.Size =
dataParameter.Size;

                                                sqlParameter.Direction =
property.Direction;
                                                sqlParameter.Value =
request.ParameterMap.GetValueOfProperty( parameterObject,
property.PropertyName );
                                        }
                                }

                                IDataParameter parameterCopy =
command.CreateParameter();
                                parameterCopy.Value = sqlParameter.Value;
                                
                                parameterCopy.Direction =
sqlParameter.Direction;

                                // With a ParameterMap, we could specify the
ParameterDbTypeProperty
                                if (_statement.ParameterMap != null)
                                {
                                        if
(request.ParameterMap.GetProperty(i).DbType.Length >0)
                                        {
                                                string dbTypePropertyName =
session.DataSource.Provider.ParameterDbTypeProperty;

        
ObjectProbe.SetPropertyValue(parameterCopy, dbTypePropertyName,
ObjectProbe.GetPropertyValue(sqlParameter, dbTypePropertyName));
                                        }
                                        else
                                        {
                                                parameterCopy.DbType =
sqlParameter.DbType;
                                        }
                                }
                                else
                                {
                                        parameterCopy.DbType =
sqlParameter.DbType;
                                }
// FIX BEGIN :
 
if(typeof(command).FullName.Equals("Oracle.DataAccess.Client.OracleCommand")
&&
                    !sqlParameter.DbType.Equals(System.Data.DbType.String))
                                    ((IDbDataParameter)parameterCopy).Size =
((IDbDataParameter)sqlParameter).Size;
// END FIX...
                                ((IDbDataParameter)parameterCopy).Precision
= ((IDbDataParameter)sqlParameter).Precision;
                                ((IDbDataParameter)parameterCopy).Scale =
((IDbDataParameter)sqlParameter).Scale;

                                parameterCopy.ParameterName =
sqlParameter.ParameterName;
                
                command.Parameters.Add(parameterCopy);
                        }
                }


Reply via email to