2012-06-22 2 views
0

Я использую NHibernate в старой базе данных с клиентом Oracle 8i. Я могу выполнить Get и Delete в таблице базы данных, но не могу сохранять или обновлять записи. Исключение состоит в следующем: sqlString состоит из вопросительных знаков, и я не знаю почему.Не удалось выполнить UPDATE или INSERT с помощью 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) 

А вот Repository класс:

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> 

Недавно мой коллега также столкнулись с какой-то проблемой преобразования Unicode/ASCII, но я никогда не думал, что это был бы ответ. Сообщение об исключении просто вводит в заблуждение ...

Благодарим Мартина за вдохновляющее предложение!

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

0

Если вы используете назначенные идентификаторы, вы не можете использовать SaveOrUpdate, поскольку NHibernate не будет знать, является ли это новым экземпляром (т.е. Сохранить/сделать вставку) или существующий экземпляр (т. е. для обновления).

Тогда вам нужно указать, вставляете ли вы новый объект (session.Save) или обновляете существующий объект (session.Update).

+0

Спасибо! Я заменил session.SaveOrUpdate() с session.Update() в этом случае. Но такое же исключение произошло и в trans.Commit(). С session.Save() он зависает в одной строке, и я все еще жду. – begeeben

+0

У вас есть антивирусное программное обеспечение? –

+0

Да, клиент Trend OfficeScan. Я попытался остановить его, закончив NTRtScan.exe и TmListen.exe в taskmgr. Но код все еще не работает. – begeeben

0

Из внешнего вида вы хотите создать новый объект и сохранить его в базе данных, но то, что вы делаете, это загрузка объекта с помощью сеанса Nhibernate, а затем обновление его свойств .. что это говорит об Nhibernate session состоит в том, что у вас есть объект, связанный с db с данным идентификатором, и теперь вы хотите обновлять определенные свойства, когда infact вы хотите, чтобы выполнялась инструкция insert.

Таким образом, правильный способ - создать новый объект MitForg, а затем позвонить Session.SaveOrUpdate(), а Nhibernate должен позаботиться о вставке после этого.

Вы также можете попробовать использовать Session.Merge().

Позвольте мне знать, если это работает для вас ..

+0

Нет, но благодарю вас за предложение! – begeeben

Смежные вопросы