WinForms 应用程序、NHibernate v3.3.x、.Net 4、Windows 7(32 位)、Oracle 10g 后端
我们正在使用带有AuditTrail
表的遗留数据库,其中列操作类型 (AKTIONSCODE) 控制附加(可选)参数 (Para1-Para4) 的含义
我创建了一个相应的类AuditTrail
;以及派生的子类AuditTrailAsmRuleSetState
,AuditTrailTestSpecSetState
其唯一目的是为公共参数获取一些不错的 getter 和 setter。
插入条目工作正常。
读取AuditTrailAsmRuleSetState
条目和其他派生类也可以正常工作。
但有时我会收到 NHibernate.WrongClassException 读取 AuditTrailTestSpecSetState 条目; 关闭应用程序(也许关闭会话?)并再次阅读相同的条目将再次起作用!?
非常感谢您的建议。
AuditTrail 表和 nHibernate 映射文件如下所示:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="MeCIS_DAL"
namespace="Com.XY.App.DAL.Entities" >
<class name="AuditTrail"
table="AUDITTRAIL" schema="MECIS_OWNER"
dynamic-update="true" dynamic-insert="true" rowid="rowid">
<id name="AID" column="AID" unsaved-value="0">
<generator class="native">
<param name="sequence">mecis_owner.seq_audittrail</param>
</generator>
</id>
<discriminator formula="case when aktionscode=20005 then '1'
when aktionscode=20010 then '2'
when aktionscode=20020 then '3'
else '10' end" />
<property name="AuditTime" column="DATUM" not-null="true" />
<many-to-one name="User" class="Bearbeiter"
fetch="join" cascade="none" not-null="true" >
<column name="BEARBEITER_ID" />
</many-to-one>
<property name="HostName" column="RECHNER" length="15" />
<many-to-one name="AuditTrailDefObj" class="AuditTrailDef"
fetch="join" cascade="none" not-null="true" >
<column name="AKTIONSCODE" />
</many-to-one>
<property name="Para1" column="PARAMETER1" length="40" />
<property name="Para2" column="PARAMETER2" length="40" />
<property name="Para3" column="PARAMETER3" length="40" />
<property name="Para4" column="PARAMETER4" length="250" />
<subclass name="AuditTrailAsmRuleSetState" discriminator-value="1" entity-name="SetStateAsmRule">
<!-- subclass specific properties -->
</subclass>
<subclass name="AuditTrailTestSpecObjSetState" discriminator-value="2" entity-name="SetStateTestSpecObj">
<!-- subclass specific properties -->
</subclass>
<subclass name="AuditTrailTestSpecSetState" discriminator-value="3" entity-name="SetStateTestSpec">
<!-- subclass specific properties -->
</subclass>
<subclass name="AuditTrail" discriminator-value="10" entity-name="BaseStd">
<!-- subclass specific properties -->
</subclass>
</class>
<!--
TABLE AUDITTRAIL
Name Null? Type
===================================================================
AID NOT NULL NUMBER(11)
DATUM NOT NULL DATE
BEARBEITER_ID NOT NULL NUMBER(5)
RECHNER VARCHAR2(15)
AKTIONSCODE NOT NULL NUMBER(5)
PARAMETER1 VARCHAR2(40)
PARAMETER2 VARCHAR2(40)
PARAMETER3 VARCHAR2(40)
PARAMETER4 VARCHAR2(250)
-->
</hibernate-mapping>
类 AuditTrail 和派生类 AuditTrailTestSpecSetState 像这样:(
派生类AuditTrailTestSpecObjSetState
和AuditTrailAsmRuleSetState
相当相似AuditTrailTestSpecSetState
)
public class AuditTrail : EntityBase
{
..constants, remarks, etc. omitted
public AuditTrail(AuditTrailType type)
{
this.Init();
this.SetAuditTrailType(type);
}
public AuditTrail(AuditTrailType type, string para1 = null, string para2 = null, string para3 = null, string para4 = null)
{
this.Init();
this.SetAuditTrailType(type);
this.Para1 = StringHelper.Truncate(para1, this.para1MaxLength);
this.Para2 = StringHelper.Truncate(para2, this.para2MaxLength);
this.Para3 = StringHelper.Truncate(para3, this.para3MaxLength);
this.Para4 = StringHelper.Truncate(para4, this.para4MaxLength);
}
public AuditTrail(AuditTrailType type, params string[] parameters)
{
this.Init();
this.SetAuditTrailType(type);
if (parameters.Length > MAXPARAMETERS)
{
throw new ArgumentException("AuditTrail: to many parameters passed. " + parameters.ToString());
}
... some code omitted
}
protected AuditTrail()
{
this.Init();
}
public virtual int AID { get; set; }
public virtual DateTime AuditTime { get; set; }
public virtual Bearbeiter User { get; set; }
public virtual int Bearbeiter_ID
{
get
{
return (this.User != null) ? this.User.Bearbeiter_Id : -1;
}
set
{
this.SetUser(value);
}
}
public virtual string Benutzername
{
get
{
if (this.User == null)
{
return string.Empty;
}
return this.User.Benutzername ?? string.Empty;
}
protected set
{
}
}
public virtual string HostName { get; set; }
public virtual AuditTrailDef AuditTrailDefObj { get; set; }
public virtual int Type
{
get
{
return this.AuditTrailDefObj != null ? (int)this.AuditTrailDefObj.Type : -1;
}
set
{
this.SetAuditTrailType((AuditTrailType)value);
}
}
public virtual string Name
{
get
{
return this.AuditTrailDefObj != null ? this.AuditTrailDefObj.Name : null;
}
}
public virtual string Para1 { get; set; }
public virtual string Para2 { get; set; }
public virtual string Para3 { get; set; }
public virtual string Para4 { get; set; }
/// <summary>Initialize this AuditTrail instance</summary>
protected void Init()
{
try
{
this.AuditTime = DateTime.Now;
this.HostName = Environment.MachineName;
this.Bearbeiter_ID = DAL.CurrentMeCISUser_Bearbeiter_Id;
}
catch (Exception ex)
{
log.Warn("Init failed but ignored", ex);
}
}
protected void SetAuditTrailType(AuditTrailType type)
{
AuditTrailDef atd = DAL.Repository.GetById<AuditTrailDef>((int)type);
if (atd == null)
{
throw new ArgumentException("SetAuditTrailType: type" + type.ToString() + " not found");
}
this.AuditTrailDefObj = atd;
}
/// <summary>set a reference to an user (BEARBEITER) instance</summary>
/// <param name="bearbeiter_ID">id of user to set (BEARBEITER.BEARBEITER_ID)</param>
protected void SetUser(int bearbeiter_ID)
{
Bearbeiter user = DAL.Repository.GetById<Bearbeiter>(bearbeiter_ID);
if (user == null)
{
throw new ArgumentException("SetUser: invalud bearbeiter_id" + bearbeiter_ID.ToString());
}
this.User = user;
}
}
}
AuditTrailTestSpecSetState:
public class AuditTrailTestSpecSetState : AuditTrail
{
public virtual int Id
{
get
{
int n = int.Parse(this.Para1);
return n;
}
protected set
{
}
}
public virtual TestSpecStates State
{
get
{
int n = int.Parse(this.Para2);
return (TestSpecStates)n;
}
}
public virtual string StateDesc
{
get
{
TestSpecStates rs = this.State;
string s = rs.ToString();
try
{
s = DAL.RscMgr.GetString("TestSpecState_" + s, CultureInfo.CurrentCulture);
}
catch (Exception)
{
log.Error("StateDesc: no rsc for state " + this.State.ToString());
}
return s;
}
}
public virtual int StatusVal
{
get
{
return (int)this.State;
}
}
}
Stacktrace/logging: SQL 语句对我来说似乎没问题。
...Com.XY.App.MgmtTool.TestSpecMgmtForm: ShowHistoryDataGrid
Com.XY.App.DAL.GenericDAOHibernate`2: GetTestSpecHistory id:1479
**NHibernate.SQL: 2012-12-12 08:26:42,488 DEBUG NHibernate.SQL: select setstatete0_.AID as AID6_, setstatete0_.DATUM as DATUM6_, setstatete0_.BEARBEITER_ID as BEARBEITER3_6_, setstatete0_.RECHNER as RECHNER6_, setstatete0_.AKTIONSCODE as AKTIONSC5_6_, setstatete0_.PARAMETER1 as PARAMETER6_6_, setstatete0_.PARAMETER2 as PARAMETER7_6_, setstatete0_.PARAMETER3 as PARAMETER8_6_, setstatete0_.PARAMETER4 as PARAMETER9_6_ from App_OWNER.AUDITTRAIL setstatete0_ where case when setstatete0_.aktionscode=20005 then '1' when setstatete0_.aktionscode=20010 then '2' when setstatete0_.aktionscode=20020 then '3' else '10' end='3' and setstatete0_.PARAMETER1=:p0 and setstatete0_.AKTIONSCODE=:p1 order by setstatete0_.AID desc;:p0 = '1479' [Type: String (0)], :p1 = 20020 [Type: Int32 (0)]**
Eine Ausnahme (erste Chance) des Typs "NHibernate.WrongClassException" ist in NHibernate.dll aufgetreten.
Eine Ausnahme (erste Chance) des Typs "NHibernate.WrongClassException" ist in NHibernate.dll aufgetreten.
Eine Ausnahme (erste Chance) des Typs "NHibernate.WrongClassException" ist in NHibernate.dll aufgetreten.
Eine Ausnahme (erste Chance) des Typs "NHibernate.WrongClassException" ist in NHibernate.dll aufgetreten.
Com.XY.App.MgmtTool.TestSpecModel: 2012-12-12 08:26:42,754 DEBUG Com.XY.App.MgmtTool.TestSpecModel: GetTestSpecHistory failed!
**NHibernate.WrongClassException: Object with id: 5436 was not of the specified subclass:** SetStateTestSpec (loading object was of wrong class [Com.XY.App.DAL.Entities.AuditTrail])
bei NHibernate.Loader.Loader.InstanceAlreadyLoaded(IDataReader rs, Int32 i, IEntityPersister persister, EntityKey key, Object obj, LockMode lockMode, ISessionImplementor session) in p:\nhibernate-core\src\NHibernate\Loader\Loader.cs:Zeile 896.
bei NHibernate.Loader.Loader.GetRow(IDataReader rs, ILoadable[] persisters, EntityKey[] keys, Object optionalObject, EntityKey optionalObjectKey, LockMode[] lockModes, IList hydratedObjects, ISessionImplementor session) in p:\nhibernate-core\src\NHibernate\Loader\Loader.cs:Zeile 872.
bei NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet, ISessionImplementor session, QueryParameters queryParameters, LockMode[] lockModeArray, EntityKey optionalObjectKey, IList hydratedObjects, EntityKey[] keys, Boolean returnProxies) in p:\nhibernate-core\src\NHibernate\Loader\Loader.cs:Zeile 342.
bei NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) in p:\nhibernate-core\src\NHibernate\Loader\Loader.cs:Zeile 473.
bei NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) in p:\nhibernate-core\src\NHibernate\Loader\Loader.cs:Zeile 251.
bei NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) in p:\nhibernate-core\src\NHibernate\Loader\Loader.cs:Zeile 1569.
bei NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters) in p:\nhibernate-core\src\NHibernate\Loader\Loader.cs:Zeile 1472.
bei NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes) in p:\nhibernate-core\src\NHibernate\Loader\Loader.cs:Zeile 1467.
bei NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.List(ISessionImplementor session, QueryParameters queryParameters) in p:\nhibernate-core\src\NHibernate\Hql\Ast\ANTLR\Loader\QueryLoader.cs:Zeile 288.
bei NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(ISessionImplementor session, QueryParameters queryParameters) in p:\nhibernate-core\src\NHibernate\Hql\Ast\ANTLR\QueryTranslatorImpl.cs:Zeile 112.
bei NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results) in p:\nhibernate-core\src\NHibernate\Engine\Query\HQLQueryPlan.cs:Zeile 105.
bei NHibernate.Impl.SessionImpl.List(String query, QueryParameters queryParameters, IList results) in p:\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs:Zeile 626.
bei NHibernate.Impl.SessionImpl.List(String query, QueryParameters parameters) in p:\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs:Zeile 592.
bei NHibernate.Impl.QueryImpl.List() in p:\nhibernate-core\src\NHibernate\Impl\QueryImpl.cs:Zeile 64.
bei Com.XY.App.DAL.TestSpecDAOHibernate.GetTestSpecHistory(Int32 id) in L:\App\DAL\DAOHibernate\TestSpecDAOHibernate.cs:Zeile 55.
bei Com.XY.App.MgmtTool.TestSpecModel.GetTestSpecHistory(Int32 id) in L:\App\MgmtTool\Model\TestSpecModel_Mgmt.cs:Zeile 221.
Com.XY.App.MgmtTool.FrmHelper: 2012-12-12 08:26:42,760 DEBUG Com.XY.App.MgmtTool.FrmHelper: ColorizeZRDataGrid 6 0