本文介绍了NHibernate被魔术串撞毁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的琐碎程序:

public class Entity
{
  public virtual long Id { get; set; }
  public virtual string Payload { get; set; }
}

class Program
{
  static void Main( string[] args )
  {
    var config = new Configuration().Configure();
    var sessionFactory = config.BuildSessionFactory();
    using ( var session = sessionFactory.OpenSession() )
    {
      var entity = new Entity { Payload = "'))" };
      session.Save( entity );
    }
  }
}

只要为Payload属性分配了任何无害的字符串(例如"Hi"),一切都会按预期进行.但是,这个特殊的魔术字符串'))使NHibernate抛出异常:'索引超出范围.尝试保存实体时,必须为非负数并且小于集合的大小.

As long as Payload property is assigned any innocent string such as 'Hi there' everything works as expected. However this particular magic string ')) makes NHibernate throw an exception: 'Index was out of range. Must be non-negative and less than the size of the collection' when it tries to save the entity.

我想知道NHibernate为什么关心参数内容.真的不应该.

I wonder why NHibernate cares of the parameter content. It really shouldn't.

或者这个样本有什么问题吗?

Or maybe something is very wrong with this sample?

NHibernate版本为2.1

NHibernate version is 2.1

SQL脚本:

create table tblEntity
(
  EntityId BIGINT NOT NULL IDENTITY PRIMARY KEY
 ,Payload VARCHAR(10) NOT NULL
)

映射:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="MyNamespace.Entity, MyAssembly"
         table="tblEntity">
    <id name="Id" column="EntityId" unsaved-value="0">
      <generator class="identity"/>
    </id>
    <property name="Payload"/>
  </class>
</hibernate-mapping>

NHibernate设置:

NHibernate settings:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
    <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
    <property name="connection.connection_string_name">Main</property>
    <property name="connection.isolation">ReadCommitted</property>
    <property name="default_schema">dbo</property>
    <property name="format_sql">true</property>
    <property name="query.substitutions">true=1;false=0</property>
    <property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
    <mapping assembly="MyAssembly"/>
  </session-factory>
</hibernate-configuration>

没有什么特别的,没有太多的错误余地.

Nothing special as you can see, not too much room for mistakes.

System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
System.ThrowHelper.ThrowArgumentOutOfRangeException()
System.Collections.Generic.List`1.get_Item(Int32 index)
NHibernate.AdoNet.Util.BasicFormatter.FormatProcess.CloseParen()
NHibernate.AdoNet.Util.BasicFormatter.FormatProcess.Perform()
NHibernate.AdoNet.Util.BasicFormatter.Format(String source)
NHibernate.AdoNet.Util.SqlStatementLogger.LogCommand(String message, IDbCommand command, FormatStyle style)
NHibernate.AdoNet.Util.SqlStatementLogger.LogCommand(IDbCommand command, FormatStyle style)
NHibernate.AdoNet.AbstractBatcher.LogCommand(IDbCommand command)
NHibernate.AdoNet.AbstractBatcher.Prepare(IDbCommand cmd)
NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd)
NHibernate.Id.IdentityGenerator.InsertSelectDelegate.ExecuteAndExtract(IDbCommand insert, ISessionImplementor session)
NHibernate.Id.Insert.AbstractReturningDelegate.PerformInsert(SqlCommandInfo insertSQL, ISessionImplementor session, IBinder binder)
NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Boolean[] notNull, SqlCommandInfo sql, Object obj, ISessionImplementor session)
NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object[] fields, Object obj, ISessionImplementor session)
NHibernate.Action.EntityIdentityInsertAction.Execute()
NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
NHibernate.Event.Default.DefaultSaveEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
NHibernate.Impl.SessionImpl.Save(Object obj)

推荐答案

我已经查看了对

NH 2.1中存在一个导致此问题的问题,此问题已在2.1.1.GA中修复.

there was an issue in NH 2.1 that caused this behavior, this was fixed in 2.1.1.GA.

Bugtracker: NH-1992

Bugtracker: NH-1992

github上的更改集:提交

Changeset on github: Commit

这篇关于NHibernate被魔术串撞毁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 23:45