我在使用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)
这是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 :(得分:0)
如果您正在使用已分配的ID,则无法使用SaveOrUpdate,因为NHibernate不会知道它是新实例(即保存/执行插入)还是现有实例(即更新)。
然后,您需要明确是否要插入新实体(session.Save)或更新现有实体(session.Update)。
答案 1 :(得分:0)
从它的外观来看,你想创建一个新对象并将其保存到数据库中,但你正在做的是使用Nhibernate Session加载对象然后更新它的属性..这告诉Nhibernate会话就是你在db中有一个与给定id相关联的对象,现在你想要更新某些属性,当你想要一个insert语句运行时。
因此,正确的方法是创建一个新的MitForg对象,然后在其上调用Session.SaveOrUpdate()
,Nhibernate应该在此后进行插入。
您也可以尝试使用Session.Merge()
。
请告诉我这是否适合您..
答案 2 :(得分:0)
原来这是一个Unicode到ASCII的转换问题。我按照以下链接中的解决方案。我们需要的是在映射文件中为所有字符串类型属性添加一个type属性,如下所示:
<property name="FORGNAME" type="AnsiString" ></property>
最近我的同事也遇到了某种Unicode / ASCII转换问题,但我从未想过它会是答案。异常消息只是误导......
感谢Martin提出鼓舞人心的建议!
NHibernate and The Case of the Crappy Oracle NHibernate and ORA-12571 Errors