nHibernate TooManyRowsAffectedException意外的行数:X;预期:1

时间:2019-02-25 10:18:02

标签: sql hibernate nhibernate orm sybase

我将nHibernate与Sybase一起使用,并且在保存到表中时出现 TooManyRowsAffectedException 意外行数:5;预期:1 ”,原因这是因为在数据库上触发了触发器。

  • 我有一个客户端基类(ClientId,ClientType,LanguageCode),应将其保存到CLIENT表中
  • 我有一个Person类(姓,名,称谓),应保存到PERSON表中
  • 我有一个组织类(OrgName,RegNo),应保存到OERGANISATION表中
  • PERSON和ORGANIZATION均从CLIENT继承。 当我保存一个人时,nHibernate首先保存到CLIENT,然后尝试保存到PERSON。

不幸的是,我不允许更改触发器(即添加“ set NOCOUNT ON”-像这里:NHibernate TooManyRowsAffectedException

相反,我需要让nHibernate忽略行数。为此,我尝试了:TooManyRowsAffectedException with encrypted triggers,但没有任何运气:

当我调用NonBatchingBatcherWithoutVerification时执行注入的已更改AddToBatch .Commit(),但仍会引发行计数异常。

在我编写自己的“ NonBatchingBatcherWithoutVerification”之前(见下文),在编写自己的注入类(没有引发行计数异常)之后,将其插入到CLIENT(第一个表)BUT中时遇到触发错误。 PERSON插入(第二插入而不是第一CLIENT插入)

我的代码如下:

设置nHibernate配置(注入了NonVerifyingBatcherFactory : IBatcherFactory)并保存到数据库:

  var cfg = new Configuration();
  cfg.DataBaseIntegration(x =>
  {
      x.ConnectionString ="Data Source='';Database=;Port='';UID='';PWD=''";
      x.Dialect<SybaseASE15Dialect>();
      x.LogSqlInConsole = true;
      x.BatchSize = 1;
      x.Driver<DriverWithCustomBatcherFactory>(); });

  cfg.DataBaseIntegration(db => db.Batcher<NonVerifyingBatcherFactory>());

  cfg.Configure();

  var sesFact = cfg.BuildSessionFactory();

  using (var session = sesFact.OpenSession()) {

      using (var tx = session.BeginTransaction()){

      Person newPerson = new Person();
      newPerson.Title = "Mr";
      newPerson.Forenames = "THOMAS";
      newPerson.Surname = "BYRNE";
      newPerson.ClientType = "P";
      newPerson.LanguageCode = "ENG";
      newPerson.NationalityCode = "GBR";
      newPerson.NormalCountryOfResidence = "GBR";

      var nextClientId = session.QueryOver<Client>()
      .Select(Projections.Max<Client>(c => c.ClientId))
      .SingleOrDefault<int>() + 1;

      session.Save(newPerson);
  tx.Commit();
  }

新注入的实现IBatcherFactory的NonVerifyingBatcherFactory类

public class NonVerifyingBatcherFactory : IBatcherFactory
{

    public virtual IBatcher CreateBatcher(ConnectionManager connectionManager, IInterceptor interceptor)
    {
        return new NonBatchingBatcherWithoutVerification(connectionManager, interceptor);

    }
}

我尝试实现AddToBatchDoExecuteBatch-都没有 VerifyOutcomeNonBatched

public class NonBatchingBatcherWithoutVerification : NonBatchingBatcher
{

    public NonBatchingBatcherWithoutVerification(ConnectionManager connectionManager, IInterceptor interceptor)
        : base(connectionManager, interceptor)
    {
        //BatchSize = 1;
    }

    public override void AddToBatch(IExpectation expectation)
    {
            IDbCommand cmd = CurrentCommand;
            ExecuteNonQuery(cmd);
            // Removed the following line
            //expectation.VerifyOutcomeNonBatched(rowCount, cmd);

    }

    protected override void DoExecuteBatch(System.Data.IDbCommand ps)
    {
        //IDbCommand cmd = CurrentCommand;
        //ExecuteNonQuery(ps);
    }
}



public class DriverWithCustomBatcherFactory : SybaseAseClientDriver, IEmbeddedBatcherFactoryProvider
{
    public Type BatcherFactoryClass
    {
        get { return typeof(NonVerifyingBatcherFactory); }
    }
}
  • 这是因为我没有使用nHibernate Fluent:
  • 或者没有正确配置分批-但是仅x.AdoNetBatchSizex.BatchSize

    cfg.DataBaseIntegration(
        x =>
        {
            x.ConnectionString ="Data Source='';Database=;Port='';UID='';PWD=''";
            x.Dialect<SybaseASE15Dialect>();
            x.LogSqlInConsole = true;
    

在hibernate.cfg.xm lfile中添加了以下内容:

<property name="adonet.factory_class">NHibernateTest.NonVerifyingBatcherFactory, NHibernateTest</property>
<property name="adonet.batch_size">100</property>

CLIENT和PERSON映射设置如下:   

<id name="ClientId" column="CLIENT_ID"  type = "int">
  <generator class="assigned"/>
</id>

<property name="LanguageCode" column="LANGUAGE_CODE" type = "string"/>
<property name="ClientType" column="CLIENT_TYPE" type = "string"/>

<joined-subclass name="Person" table="PERSON">
  <key column="CLIENT_ID" />
  <property name="Surname" column="SURNAME"/>
</joined-subclass>

<id name = "ID">
  <generator class = "native"/>
</id>

<property name = "CLIENT_ID"/>
<property name = "SURNAME"/>
<property name = "FORENAMES"/>


重获 保存到PERSON表时,首先将CLIENT记录保存到CLINE表-(继承并保存在.hbm.xml文件中)

如果配置中不存在adonet.factory_class和adonet.batch_size ,我会得到: TooManyRowsAffectedException 意外行数:** 5; 预期:1 **” <<-我认为是来自CLIENT触发器

如果config中存在adonet.factory_class和adonet.batch_size ,我会得到: TooManyRowsAffectedException 意外的行数:** 32; 预期:1 **” <<-从我认为的PERSON触发器

任何帮助将不胜感激,谢谢!

0 个答案:

没有答案