0

我在带有 Oracle 8i 客户端的旧数据库上使用 NHibernate。我可以对数据库表执行 Get 和 Delete,但不能保存或更新条目。例外情况如下, sqlString 由问号组成,我不知道为什么。

Nhibernate.Exceptions.GenericADOException:

    {"could not update: [MIAP.Domain.Entities.MITFORG#3][SQL: UPDATE MITFORG SET TREELEVEL = ?, PARTENTID = ?, FORGNAME = ?, FORGINFO = ?, ACTIVE = ?, MUTATOR = ?, INPDATETIME = ?, UPDDATETIME = ? WHERE FORGID = ?]"}

这是我的实体类和映射:

public class MITFORG {
    private long fORGID;
    private long? tREELEVEL;
    private long? pARTENTID;
    private string fORGNAME;
    private string fORGINFO;
    private string aCTIVE;
    private long? mUTATOR;
    private DateTime? iNPDATETIME;
    private DateTime? uPDDATETIME;
    public MITFORG() { }
    public virtual long FORGID {
        get {
            return this.fORGID;
        }
        set {
            this.fORGID = value;
        }
    }
    public virtual long? TREELEVEL
    {
        get {
            return this.tREELEVEL;
        }
        set {
            this.tREELEVEL = value;
        }
    }
    public virtual long? PARTENTID
    {
        get {
            return this.pARTENTID;
        }
        set {
            this.pARTENTID = value;
        }
    }
    public virtual string FORGNAME {
        get {
            return this.fORGNAME;
        }
        set {
            this.fORGNAME = value;
        }
    }
    public virtual string FORGINFO {
        get {
            return this.fORGINFO;
        }
        set {
            this.fORGINFO = value;
        }
    }
    public virtual string ACTIVE {
        get {
            return this.aCTIVE;
        }
        set {
            this.aCTIVE = value;
        }
    }
    public virtual long? MUTATOR
    {
        get {
            return this.mUTATOR;
        }
        set {
            this.mUTATOR = value;
        }
    }
    public virtual DateTime? INPDATETIME
    {
        get {
            return this.iNPDATETIME;
        }
        set {
            this.iNPDATETIME = value;
        }
    }
    public virtual DateTime? UPDDATETIME
    {
        get {
            return this.uPDDATETIME;
        }
        set {
            this.uPDDATETIME = value;
        }
    }
}



<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping assembly="MIAP.Domain" namespace="MIAP.Domain.Entities" xmlns="urn:nhibernate-mapping-2.2">
  <class name="MITFORG" table="MITFORG" lazy="true" >
    <id name="FORGID">
      <generator class="assigned" />
    </id>
    <property name="TREELEVEL"></property>
    <property name="PARTENTID"></property>
    <property name="FORGNAME"></property>
    <property name="FORGINFO"></property>
    <property name="ACTIVE"></property>
    <property name="MUTATOR"></property>
    <property name="INPDATETIME"></property>
    <property name="UPDDATETIME"></property>
  </class>
</hibernate-mapping>

我检查了属性名称和表列名称。由于 FORGID 是由应用程序分配的,因此我将生成器类更改为“已分配”。它也不适用于“身份”。有人可以指点我调试这个的方向吗?

已编辑:保存条目的代码

    Dim mitforgRepository As New MITFORGRepository
    Dim mitforg As MITFORG = mitforgRepository.GetById(3)
    mitforg.FORGINFO = "T"
    mitforg.ACTIVE = "Y"
    mitforg.FORGINFO = "T"
    mitforg.INPDATETIME = Now
    mitforg.MUTATOR = 324
    mitforg.PARTENTID = 335
    mitforg.TREELEVEL = 1
    mitforg.UPDDATETIME = Now
    mitforgRepository .Save(mitforg)

这是存储库类:

using System;
using System.Collections.Generic;
using System.Text;
using NHibernate;
using MIAP.Domain.Entities;

namespace MIAP.Domain.Repositories
{
    public class MITFORGRepository : IRepository<MITFORG, Int64?>
    {
        private static ISession GetSession()
        {
            return SessionProvider.SessionFactory.OpenSession();
        }

        public MITFORG GetById(Int64? id)
        {
            using (ISession session = GetSession())
            {
                return session.Get<MITFORG>(id);
            }
        }

        public void Save(MITFORG saveObj)
        {
            using (ISession session = GetSession())
            {
                using (ITransaction trans = session.BeginTransaction())
                {
                    session.SaveOrUpdate(saveObj);
                    trans.Commit();
                }
            }
        }

        public void Delete(MITFORG delObj)
        {
            using (ISession session = GetSession())
            {
                using (ITransaction trans = session.BeginTransaction())
                {
                    session.Delete(delObj);
                    trans.Commit();
                }
            }
        }
    }
}

InnerException 是 System.Data.OracleClient.OracleException,ORA-12571

这是堆栈跟踪:

   於 System.Data.OracleClient.OracleConnection.CheckError(OciErrorHandle errorHandle, Int32 rc)
   於 System.Data.OracleClient.OracleCommand.Execute(OciStatementHandle statementHandle, CommandBehavior behavior, Boolean needRowid, OciRowidDescriptor& rowidDescriptor, ArrayList& resultParameterOrdinals)
   於 System.Data.OracleClient.OracleCommand.ExecuteNonQueryInternal(Boolean needRowid, OciRowidDescriptor& rowidDescriptor)
   於 System.Data.OracleClient.OracleCommand.ExecuteNonQuery()
   於 NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd) 於 c:\Users\oskar.berggren\Documents\Projects\nhibernate-core-3\src\NHibernate\AdoNet\AbstractBatcher.cs: 行 203
   於 NHibernate.AdoNet.NonBatchingBatcher.AddToBatch(IExpectation expectation) 於 c:\Users\oskar.berggren\Documents\Projects\nhibernate-core-3\src\NHibernate\AdoNet\NonBatchingBatcher.cs: 行 40
   於 NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session) 於 c:\Users\oskar.berggren\Documents\Projects\nhibernate-core-3\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs: 行 2799
4

3 回答 3

0

如果您使用分配的 id,则不能使用 SaveOrUpdate,因为 NHibernate 不知道它是新实例(即保存/执行插入)还是现有实例(即更新)。

然后,您需要明确您是插入新实体 (session.Save) 还是更新现有实体 (session.Update)。

于 2012-06-22T07:56:40.710 回答
0

从外观上看,您想创建一个新对象并将其保存到数据库中,但您正在做的是使用 Nhibernate 会话加载对象,然后更新它的属性.. 这告诉 Nhibernate 会话是您在 db 中有一个与给定 id 关联的对象,现在您想要更新某些属性,而实际上您想要运行插入语句。

因此正确的方法是创建一个新的 MitForg 对象,然后调用Session.SaveOrUpdate()它,然后 Nhibernate 应该负责随后的插入。

您也可以尝试使用Session.Merge().

让我知道这是否适合你..

于 2012-06-22T10:03:36.907 回答
0

原来这是一个 Unicode 到 ASCII 转换问题。我遵循以下链接中的解决方案。需要为映射文件中的所有字符串类型属性添加类型属性,如下所示:

<property name="FORGNAME"  type="AnsiString" ></property>

最近我的同事也遇到了某种 Unicode/ASCII 转换问题,但我没想到会是答案。异常消息只是误导......

感谢马丁的鼓舞人心的建议!

NHibernate 和糟糕的 Oracle NHibernate 和 ORA-12571 错误案例

于 2012-06-22T15:18:30.863 回答