2012-06-22 115 views
0

我在使用Oracle 8i客戶端的舊數據庫上使用NHibernate。我可以在數據庫表上執行Get和Delete,但不能保存或更新條目。異常如下,sqlString由問號組成,我不知道爲什麼。無法使用NHibernate更新或插入

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 
+0

SQL中的問號是參數佔位符。參數值通常在查詢結尾。你可以添加試圖保存對象的代碼嗎? –

+0

謝謝!我在問題中添加了代碼。 – begeeben

+0

我還添加了它的InnerException的堆棧跟蹤。 – begeeben

回答

0

原來這是一個Unicode到ASCII的轉換問題。我在下面的鏈接中遵循瞭解決方案。我們需要的是增加一個類型的屬性在這樣的映射文件中的所有字符串類型的屬性:

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

最近我的同事也遇到了某種統一字符編碼/ ASCII轉換問題,但我從來沒有想到會一直答案。例外信息只是誤導...

感謝馬丁的鼓舞人心的建議!

NHibernate and The Case of the Crappy Oracle NHibernate and ORA-12571 Errors

0

如果你使用指定的id,你不能使用SaveOrUpdate,因爲NHibernate不會知道它是否是一個新的實例(即。保存/插入)或現有實例(即更新)。

然後,您需要明確您是插入新實體(session.Save)還是更新現有實體(session.Update)。

+0

謝謝!在這種情況下,我用session.Update()替換了session.SaveOrUpdate()。但是在trans.Commit()中也發生了同樣的異常。使用session.Save(),它掛在同一行,我仍在等待。 – begeeben

+0

你有沒有運行防病毒軟件? –

+0

是,趨勢防毒牆網絡版客戶端。我試圖通過在taskmgr中結束NTRtScan.exe和TmListen.exe來終止它。但是代碼似乎仍然不起作用。 – begeeben

0

從它的外觀,你想創建一個新的對象,並將其保存到數據庫中,但你在做什麼是使用Nhibernate會話加載對象,然後更新它的屬性..這是什麼告訴Nhibernate會話是你有一個對象與數據庫關聯的具有給定的ID,現在你想更新某些屬性,當你想要一個插入語句運行。

因此,正確的方法是創建一個新的MitForg對象,然後在其上調用Session.SaveOrUpdate(),然後Nhibernate應該處理其後的插入。

您也可以嘗試使用Session.Merge()

讓我知道這是否爲你..

+0

不,但仍然謝謝你的建議! – begeeben