I’m using NHibernate on a legacy database with Oracle 8i client. I can perform Get and Delete on the database table, but can’t save or update entries. The exception is as follow, the sqlString consists of question marks and I don’t know why.
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 = ?]"}
Here are my entity class and mapping:
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>
I’ve checked property names and table column names. Since the FORGID is assigned by the application, I changed the generator class to “assigned”. It doesn’t work with “identity” either. Could someone please point me the direction to debug this?
Edited: Code to save entries
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)
And here is the Repository class:
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();
}
}
}
}
}
The InnerException is System.Data.OracleClient.OracleException, ORA-12571
And here’s the stack trace:
於 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
Turns out it’s a Unicode to ASCII conversion problem. I followed the solution in the links below. What’s needed is adding a type attribute to all string type properties in the mapping file like this:
Recently my colleague also encountered some kind of Unicode/ASCII conversion problem but I never thought it would have been the answer. The exception message is just misleading…
Thank Martin for the inspiring suggestion!
NHibernate and The Case of the Crappy Oracle
NHibernate and ORA-12571 Errors