我的问题是在这里保存NHibernate实体是(伪)代码:
using (var session = OpenSession())
{
using (var trans = session.BeginTransaction())
{
var reportTemplateVersion =
new ReportTemplateVersion
{
ReportTemplateVersionOid = "0B89DB6-6CC1-460A-B913-10AFCF0C868 ",
Description = "Testing",
TextID_Description = "144bbdda-3249-4c51-8371-3c7ee551b75b ",
ChangeTimeStamp = DateTime.Now,
HasBeenUsed = false,
PartFactory = "010",
ObjVersion = 1,
Version = 1,
ReportTemplateOid = "93822BF-B275-44A5-9F29-AF65025C03C ",
CnSubIn = 1,
CnoteIn = "15214",
CnSubOut = null,
CnoteOut = null
};
session.Save(reportTemplateVersion)
trans.Commit(); <--- here I get the exception
}
}
这是实体和映射:
public class ReportTemplateVersion
{
public ReportTemplateVersion()
{
ReportCells = new HashSet<ReportCell>();
ReportOrderRows = new HashSet<ReportOrderRow>();
}
public virtual string ReportTemplateVersionOid { get; set; }
public virtual string ReportTemplateOid { get; set; }
public virtual string Description { get; set; }
public virtual string TextID_Description { get; set; }
public virtual DateTime ChangeTimeStamp { get; set; }
public virtual bool? HasBeenUsed { get; set; }
public virtual string CnoteIn { get; set; }
public virtual decimal CnSubIn { get; set; }
public virtual string CnoteOut { get; set; }
public virtual decimal? CnSubOut { get; set; }
public virtual string PartFactory { get; set; }
public virtual int ObjVersion { get; set; }
public virtual decimal Version { get; set; }
public virtual ReportTemplate ReportTemplate { get; set; }
public virtual ISet<ReportCell> ReportCells { get; set; }
public virtual ISet<ReportOrderRow> ReportOrderRows { get; set; }
public virtual CnSubGroup CnSubGroupOut { get; set; }
public virtual CnSubGroup CnSubGroupIn { get; set; }
}
public class ReportTemplateVersionMap : ClassMap<ReportTemplateVersion>
{
public ReportTemplateVersionMap()
{
Table(@"REPORTTEMPLATEVERSION");
LazyLoad();
Id(x => x.ReportTemplateVersionOid)
.Column("REPORTTEMPLATEVERSIONOID")
.CustomType("String")
.Access.Property()
.CustomSqlType("CHAR")
.Not.Nullable()
.Length(38)
.GeneratedBy.Assigned();
Map(x => x.ReportTemplateOid)
.Column("REPORTTEMPLATEOID")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("CHAR")
.Length(38);
Map(x => x.Description)
.Column("DESCRIPTION")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("NVARCHAR2")
.Length(255);
Map(x => x.TextID_Description)
.Column("TEXTID_DESCRIPTION")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("CHAR")
.Length(38);
Map(x => x.ChangeTimeStamp)
.Column("CHANGETIMESTAMP")
.CustomType("DateTime")
.Access.Property()
.Generated.Never()
.CustomSqlType("DATE");
Map(x => x.HasBeenUsed)
.Column("HASBEENUSED")
.CustomType("Boolean")
.Access.Property()
.Generated.Never()
.CustomSqlType("NUMBER")
.Precision(1);
Map(x => x.CnoteIn)
.Column("CNOTEIN")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("VARCHAR2")
.Not.Nullable()
.Length(10);
Map(x => x.CnSubIn)
.Column("CNSUBIN")
.CustomType("Decimal")
.Access.Property()
.Generated.Never()
.CustomSqlType("NUMBER")
.Not.Nullable();
Map(x => x.CnoteOut)
.Column("CNOTEOUT")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("VARCHAR2")
.Length(10);
Map(x => x.CnSubOut)
.Column("CNSUBOUT")
.CustomType<decimal?>()
.Access.Property()
.Generated.Never()
.CustomSqlType("NUMBER");
Map(x => x.PartFactory)
.Column("PARTFACTORY")
.CustomType("String")
.Access.Property()
.Generated.Never()
.CustomSqlType("CHAR")
.Not.Nullable()
.Length(3);
Version(x => x.ObjVersion)
.Column("OBJVERSION")
.CustomType("Int32")
.Access.Property()
.Generated.Never()
.CustomSqlType("NUMBER")
.Precision(38);
Map(x => x.Version)
.Column("VERSION")
.CustomType("Decimal")
.Access.Property()
.Generated.Never()
.CustomSqlType("NUMBER")
.Not.Nullable()
.Precision(38);
References(x => x.ReportTemplate)
.Class<ReportTemplate>()
.Access.Property()
.Cascade.None()
.LazyLoad()
.Not.Insert()
.Not.Update()
.Columns("REPORTTEMPLATEOID");
HasMany(x => x.ReportCells)
.Access.Property()
.AsSet()
// There are no business rules stopping us from deleting a ReportCell when its ReportTemplateVersion
// is deleted so we let nhibernate take care of it for us.
.Cascade.Delete()
.LazyLoad()
.Inverse()
.Generic()
.KeyColumns.Add("REPORTTEMPLATEVERSIONOID", mapping => mapping.Name("REPORTTEMPLATEVERSIONOID")
.SqlType("CHAR")
.Nullable()
.Length(38));
HasMany(x => x.ReportOrderRows)
.Access.Property()
.AsSet()
.Cascade.None()
.LazyLoad()
.Inverse()
.Generic()
.KeyColumns.Add("REPORTTEMPLATEVERSIONOID", mapping => mapping.Name("REPORTTEMPLATEVERSIONOID")
.SqlType("CHAR")
.Nullable()
.Length(38));
References(x => x.CnSubGroupOut)
.Class<CnSubGroup>()
.Access.Property()
.Cascade.None()
.Not.Insert()
.Not.Update()
.LazyLoad()
.Columns("CNOTEOUT", "CNSUBOUT", "PARTFACTORY");
References(x => x.CnSubGroupIn)
.Class<CnSubGroup>()
.Access.Property()
.Cascade.None()
.Not.Insert()
.Not.Update()
.LazyLoad()
.Columns("CNOTEIN", "CNSUBIN", "PARTFACTORY");
}
}
提交时我得到以下异常:
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
Stack trace:
at System.Collections.ArrayList.get_Item(Int32 index)
at Oracle.ManagedDataAccess.Client.OracleParameterCollection.GetParameter(Int32 index)
at System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item(Int32 index)
at NHibernate.Type.Int32Type.Set(IDbCommand rs, Object value, Int32 index)
at NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value, Int32 index)
at NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, Object value, Int32 index, ISessionImplementor session)
at 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)
at NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session)
at NHibernate.Action.EntityUpdateAction.Execute()
at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
at NHibernate.Engine.ActionQueue.ExecuteActions()
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event)
at NHibernate.Impl.SessionImpl.Flush()
我正在运行NHibernate 4.03并针对Oracle 12运行。
答案 0 :(得分:2)
事实证明这是我预期的映射问题,但很难找到。
问题在于相关属性:
public virtual CnSubGroup CnSubGroupOut { get; set; }
public virtual CnSubGroup CnSubGroupIn { get; set; }
CnSubGroup实体也有版本映射,当NHibernate刷新它的状态并尝试加载这些实体时会发生错误。
当我检查CnSubGroup的映射时,我发现了以下内容:
References(x => x.MainCnSubGroup)
.Class<CnSubGroup>()
.Access.Property()
.Cascade.None()
.LazyLoad()
.Columns("MAINCNOTE", "MAINCNSUB", "PARTFACTORY");
NHibernate不支持使用Composite键插入或更新引用,所有这些引用都应该映射为readonly:
References(x => x.MainCnSubGroup)
.Class<CnSubGroup>()
.Access.Property()
.Cascade.None()
.LazyLoad()
.Not.Insert()
.Not.Update()
.Columns("MAINCNOTE", "MAINCNSUB", "PARTFACTORY");
通过此代码更改,错误消失了。
答案 1 :(得分:1)
我有相同的错误消息,这也是列映射问题。
我的情况是我重复定义了已经在组件中定义的属性。
此错误的根本原因是由于参数索引(我相信在大多数情况下,Id的索引)超出了参数集合。
public class A()
{
public virtual string aaa{get;set;}
public virtual string bbb{get;set;} //bbb is defined in the BBB already!!!
public virtual BBB bigB{get;set;}
}
public class BBB(){
public virtual string bbb{get;set;}
}