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

見た目からすると、新しいオブジェクトを作成してデータベースに保存する必要がありますが、実際に行っているのは、Nhibernate セッションを使用してオブジェクトをロードし、そのプロパティを更新することです。これが Nhibernate セッションに伝えることは、指定された ID を持つオブジェクトが db に関連付けられており、insert ステートメントを実行したいときに特定のプロパティを更新したいとします。

したがって、正しい方法は、新しい MitForg オブジェクトを作成し、それを呼び出すSession.SaveOrUpdate()ことです。その後、Nhibernate が挿入を処理する必要があります。

を使ってみることもできますSession.Merge()

これがうまくいくかどうか教えてください..

于 2012-06-22T10:03:36.907 に答える
0

割り当てられた ID を使用している場合は、SaveOrUpdate を使用できません。NHibernate は、それが新しいインスタンス (つまり、保存/挿入を行うため) なのか、既存のインスタンス (つまり、更新するため) なのかを認識できないためです。

次に、新しいエンティティを挿入するか (session.Save)、既存のエンティティを更新するか (session.Update) を明示する必要があります。

于 2012-06-22T07:56:40.710 に答える
0

Unicode から ASCII への変換の問題であることが判明しました。以下のリンクの解決策に従いました。必要なのは、次のように、マッピング ファイル内のすべての文字列型プロパティに type 属性を追加することです。

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

最近、私の同僚も何らかの Unicode/ASCII 変換の問題に遭遇しましたが、それが解決策になるとは思いもしませんでした。例外メッセージは誤解を招くだけです...

感動的な提案をしてくれたMartinに感謝します!

NHibernate とくだらない Oracle NHibernate と ORA-12571 エラーの事例

于 2012-06-22T15:18:30.863 に答える