C# 异常NHibernate复合ID子级联
我与nhibernate有一段时间的问题,但一直无法解决,请尝试清楚地描述问题。 我想使用NHibernate的功能保存和编辑通过FK连接到级联父对象的对象列表。 我不明白我哪里错了,谁能帮我 数据库上的表格包括:C# 异常NHibernate复合ID子级联,c#,sql,.net,nhibernate,hql,C#,Sql,.net,Nhibernate,Hql,我与nhibernate有一段时间的问题,但一直无法解决,请尝试清楚地描述问题。 我想使用NHibernate的功能保存和编辑通过FK连接到级联父对象的对象列表。 我不明白我哪里错了,谁能帮我 数据库上的表格包括: CREATE TABLE [Evento].[Eventi]( [CodiceEvento] [varchar](20) NOT NULL, [CodiceTipoEvento] [smallint] NOT NULL, [CodiceTipoAltroEve
CREATE TABLE [Evento].[Eventi](
[CodiceEvento] [varchar](20) NOT NULL,
[CodiceTipoEvento] [smallint] NOT NULL,
[CodiceTipoAltroEvento] [smallint] NULL,
[CodiceTipoClasseEvento] [tinyint] NOT NULL,
[CodiceTipoCausaEvento] [tinyint] NULL,
[CodiceTipoStatoSchedaEvento] [tinyint] NOT NULL,
[DescrizioneEvento] [varchar](1000) NULL
CONSTRAINT [PK_Eventi] PRIMARY KEY CLUSTERED
(
[CodiceEvento] ASC
)
CREATE TABLE [Evento].[EventiDettaglioBeneInteressato](
[CodiceEvento] [varchar](20) NOT NULL,
[PrgOrdinamento] [tinyint] NOT NULL,
[CodiceTipoBeneRFI] [smallint] NOT NULL,
[DescrizioneAltroBeneRFI] [varchar](255) NULL,
[CodiceTipoRame] [varchar](25) NULL,
[CodiceTipoUnitaMisura] [tinyint] NULL,
[NumQuantita] [bigint] NULL,
CONSTRAINT [PK_EventiDettaglioBeneInteressato] PRIMARY KEY CLUSTERED
(
[CodiceEvento] ASC,
[PrgOrdinamento] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [Evento].[EventiDettaglioBeneInteressato] WITH NOCHECK ADD CONSTRAINT [FK_EventiDettaglioBeneInteressato_Eventi] FOREIGN KEY([CodiceEvento])
REFERENCES [Evento].[Eventi] ([CodiceEvento])
ON DELETE CASCADE
NOT FOR REPLICATION
GO
映射事件:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping assembly="Data.Model" namespace="Data.Model.Domain.Eventi" xmlns="urn:nhibernate-mapping-2.2">
<class name="Eventi" table="Eventi" lazy="true" schema="Evento">
<id name="CodiceEvento" column="CodiceEvento" />
<many-to-one name="TipiEvento" update="false" insert="false">
<column name="CodiceTipoEvento" sql-type="smallint" not-null="true" />
</many-to-one>
<property name="CodiceTipoEvento" >
<column name="CodiceTipoEvento" sql-type="smallint" not-null="true" />
</property>
<many-to-one name="TipiAltroEvento" update="false" insert="false">
<column name="CodiceTipoAltroEvento" sql-type="smallint" not-null="false" />
</many-to-one>
<property name="CodiceTipoAltroEvento" >
<column name="CodiceTipoAltroEvento" sql-type="smallint" not-null="false" />
</property>
<many-to-one name="TipiClasseEvento" update="false" insert="false">
<column name="CodiceTipoClasseEvento" sql-type="tinyint" not-null="true" />
</many-to-one>
<property name="CodiceTipoClasseEvento">
<column name="CodiceTipoClasseEvento" sql-type="tinyint" not-null="true" />
</property>
<many-to-one name="TipiCausaEvento" update="false" insert="false">
<column name="CodiceTipoCausaEvento" sql-type="tinyint" />
</many-to-one>
<property name="CodiceTipoCausaEvento" >
<column name="CodiceTipoCausaEvento" sql-type="tinyint" />
</property>
<many-to-one name="TipiStatoSchedaEvento" update="false" insert="false">
<column name="CodiceTipoStatoSchedaEvento" sql-type="tinyint" not-null="true" />
</many-to-one>
<property name="CodiceTipoStatoSchedaEvento">
<column name="CodiceTipoStatoSchedaEvento" sql-type="tinyint" not-null="true" />
</property>
<many-to-one name="GestoriAsset" update="false" insert="false">
<column name="CodiceGestoreAsset" sql-type="int" not-null="false" />
</many-to-one>
<property name="CodiceGestoreAsset">
<column name="CodiceGestoreAsset" sql-type="int" not-null="false" />
</property>
<many-to-one name="TipiOraEvento" update="false" insert="false">
<column name="CodiceTipoOraEvento" sql-type="tinyint" not-null="false" />
</many-to-one>
<property name="CodiceTipoOraEvento">
<column name="CodiceTipoOraEvento" sql-type="tinyint" not-null="false" />
</property>
<many-to-one name="TipiAutoreEvento" update="false" insert="false">
<column name="CodiceTipoAutoreEvento" sql-type="smallint" not-null="false" />
</many-to-one>
<property name="CodiceTipoAutoreEvento">
<column name="CodiceTipoAutoreEvento" sql-type="smallint" not-null="false" />
</property>
<many-to-one name="TipiSegnalazioneEvento" update="false" insert="false">
<column name="CodiceTipoSegnalazioneEvento" sql-type="smallint" not-null="false" />
</many-to-one>
<property name="CodiceTipoSegnalazioneEvento">
<column name="CodiceTipoSegnalazioneEvento" sql-type="smallint" not-null="false" />
</property>
<property name="DescrizioneEvento">
<column name="DescrizioneEvento" sql-type="varchar" not-null="false" />
</property>
<bag name="EventiDettaglio" table="EventiDettaglioBeneInteressato" schema="Evento" inverse="true" cascade="all,delete-orphan" >
<key column="CodiceEvento" />
<one-to-many class="EventiDettaglioBeneInteressato" />
</bag>
</class>
</hibernate-mapping>
测试:
[TestMethod]
公共无效事件
{
var codiceEvento=“20140630_013325_BA”;
使用(var session=IoC.Container.Resolve().OpenSession())
{
var evento=session.Get(codiceEvento);
AreEqual(evento.EventiDettaglio.Count,0);
var beneeinterestato=new Data.Model.Domain.Eventi.eventidettagileobeneinteresto();
Beneinestarato.PrgOrdinamento=1;
beneinteresato.Evento=Evento;
beneriestato.CodiceTipoBeneRFI=1;
evento.EventiDettaglio.Add(beneriestato);
var beneeinterestato2=new Data.Model.Domain.Eventi.eventidettagileobeneinteresto();
Beneinestarato.PrgOrdinamento=2;
beneinteresato.Evento=Evento;
beneriestato.CodiceTipoBeneRFI=2;
evento.EventiDettaglio.Add(beneriestato2);
session.SaveOrUpdate(evento);
session.Flush();
}
}
错误:
信息:
无法将值NULL插入到“CodiceEvento”列、表“Evento.EventidettagileObeNeInteressTo”中;列不允许空值。插入失败。
声明已终止。
堆栈跟踪:
位于System.Data.SqlClient.SqlConnection.OneError(SqlException异常,布尔断开连接,操作'1 wrapCloseInAction)
位于System.Data.SqlClient.SqlInternalConnection.OneError(SqlException异常,布尔断开连接,操作'1 wrapCloseInAction)
位于System.Data.SqlClient.TdsParser.ThroweException和Warning(TdsParserStateObject StateObjectStateObj、布尔调用方连接锁、布尔异步关闭)
位于System.Data.SqlClient.TdsParser.TryRun(RunBehavior RunBehavior、SqlCommand cmdHandler、SqlDataReader dataStream、BulkCopySimpleResultSet bulkCopyHandler、TdsParserStateObject stateObj、Boolean和dataReady)
位于System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds、RunBehavior、String ResetOptions String)
位于System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior、RunBehavior RunBehavior、Boolean returnStream、Boolean async、Int32超时、任务和任务、Boolean asyncWrite、SqlDataReader ds)
位于System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior RunBehavior、Boolean returnStream、String方法、TaskCompletionSource`1 completion、Int32超时、Task&Task、Boolean asyncWrite)
位于System.Data.SqlClient.SqlCommand.InternalExecuteOnQuery(TaskCompletionSource`1完成,字符串方法名,布尔sendToPipe,Int32超时,布尔异步写入)
位于System.Data.SqlClient.SqlCommand.ExecuteOnQuery()处
位于System.Data.SqlClient.SqlCommand.ExecuteBatchRPCCommand()处
位于System.Data.SqlClient.SqlCommandSet.ExecuteOnQuery()处
在NHibernate.adonnet.SqlClientSqlCommandSet.ExecuteNonQuery()处
在NHibernate.AdoNet.SqlClientBatchingBatcher.DoExecuteBatch(idbps命令)
日志:
18:15:25.695[10]警告NHibernate.Engine.ForeignKeys-无法确定具有指定标识符Data.Model.Domain.eventide.eventidettagileobeneinteresto的Data.Model.Domain.eventide.eventidettagileobeneinteresto是暂时的还是分离的;查询数据库。在会话中使用显式Save()或Update()可防止出现这种情况。
18:15:25.716[10]警告NHibernate.Engine.ForeignKeys-无法确定具有指定标识符Data.Model.Domain.eventide.eventidettagileobeneinteresto的Data.Model.Domain.eventide.eventidettagileobeneinteresto是暂时的还是分离的;查询数据库。在会话中使用显式Save()或Update()可防止出现这种情况。
18:15:25.960[10]WARN NHibernate.Util.ADOExceptionReporter-System.Data.SqlClient.SqlException(0x80131904):无法将值NULL插入列'CodiceEvento',表'Evento.eventidettagileobeneinteresto';列不允许空值。插入失败。
声明已终止。
位于System.Data.SqlClient.SqlConnection.OneError(SqlException异常,布尔断开连接,操作'1 wrapCloseInAction)
位于System.Data.SqlClient.SqlInternalConnection.OneError(SqlException异常,布尔断开连接,操作'1 wrapCloseInAction)
位于System.Data.SqlClient.TdsParser.ThroweException和Warning(TdsParserStateObject StateObjectStateObj、布尔调用方连接锁、布尔异步关闭)
位于System.Data.SqlClient.TdsParser.TryRun(RunBehavior RunBehavior、SqlCommand cmdHandler、SqlDataReader dataStream、BulkCopySimpleResultSet bulkCopyHandler、TdsParserStateObject stateObj、Boolean和dataReady)
位于System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds、RunBehavior、String ResetOptions String)
位于System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior、RunBehavior RunBehavior、Boolean returnStream、Boolean async、Int32超时、任务和任务、Boolean asyncWrite、SqlDataReader ds)
位于System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior RunBehavior、Boolean returnStream、String方法、TaskCompletionSource`1 completion、Int32超时、Task&Task、Boolean asyncWrite)
位于System.Data.SqlClient.SqlCommand.InternalExecuteOnQuery(TaskCompletionSource`1完成,字符串方法名,布尔sendToPipe,Int32超时,布尔异步写入)
位于System.Data.SqlClient.SqlCommand.ExecuteOnQuery()处
位于System.Data.SqlClient.SqlCommand.ExecuteBatchRPCCommand()处
位于System.Data.SqlClient.SqlCommandSet.ExecuteOnQuery()处
在NHibernate.adonnet.SqlClientSqlCommandSet.ExecuteNonQuery()处
在NHibernate.AdoNet.SqlClientBatchingBatcher.DoExecuteBatch(idbps命令)
康涅狄奥尼酒店
using System;
using System.Text;
using System.Collections.Generic;
using Data.Model.Attributes;
namespace Data.Model.Domain.Eventi
{
[Serializable, Observable]
public class Eventi : Entity, IEntity
{
public Eventi()
{
EventiDettaglio = new List<EventiDettaglioBeneInteressato>();
}
public virtual string CodiceEvento { get; set; }
public virtual string DescrizioneEvento { get; set; }
public virtual TipiEvento TipiEvento { get; set; }
public virtual TipiAltroEvento TipiAltroEvento { get; set; }
public virtual TipiClasseEvento TipiClasseEvento { get; set; }
public virtual TipiCausaEvento TipiCausaEvento { get; set; }
public virtual TipiStatoSchedaEvento TipiStatoSchedaEvento { get; set; }
public virtual GestoriAsset GestoriAsset { get; set; }
public virtual TipiOraEvento TipiOraEvento { get; set; }
public virtual TipiAutoreEvento TipiAutoreEvento { get; set; }
public virtual TipiSegnalazioneEvento TipiSegnalazioneEvento { get; set; }
public virtual short CodiceTipoEvento { get; set; }
public virtual short? CodiceTipoAltroEvento { get; set; }
public virtual byte CodiceTipoClasseEvento { get; set; }
public virtual byte? CodiceTipoCausaEvento { get; set; }
public virtual byte CodiceTipoStatoSchedaEvento { get; set; }
public virtual int? CodiceGestoreAsset { get; set; }
public virtual byte? CodiceTipoOraEvento { get; set; }
public virtual short? CodiceTipoAutoreEvento { get; set; }
public virtual short? CodiceTipoSegnalazioneEvento { get; set; }
public virtual IList<EventiDettaglioBeneInteressato> EventiDettaglio { get; set; }
#region NHibernate Composite Key Requirements
public override bool Equals(object obj)
{
if (obj == null) return false;
var t = obj as Eventi;
if (t == null) return false;
if (CodiceEvento == t.CodiceEvento)
return true;
return false;
}
public override int GetHashCode()
{
int hash = GetType().GetHashCode();
hash = (hash * 397) ^ CodiceEvento.GetHashCode();
return hash;
}
#endregion
}
}
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping assembly="Data.Model" namespace="Data.Model.Domain.Eventi" xmlns="urn:nhibernate-mapping-2.2">
<class name="EventiDettaglioBeneInteressato" table="EventiDettaglioBeneInteressato" schema="Evento" lazy="true" >
<composite-id>
<key-property name="PrgOrdinamento" column="PrgOrdinamento" />
<key-many-to-one class="Data.Model.Domain.Eventi.Eventi, Data.Model" name="Evento">
<column name="CodiceEvento" />
</key-many-to-one>
</composite-id>
<property name="DescrizioneAltroBeneRFI">
<column name="DescrizioneAltroBeneRFI" sql-type="varchar" not-null="false" />
</property>
<property name="NumQuantita">
<column name="NumQuantita" sql-type="bigint" not-null="false" />
</property>
<many-to-one name="TipiBeneRFI" update="false" insert="false">
<column name="CodiceTipoBeneRFI" sql-type="smallint" not-null="true" />
</many-to-one>
<property name="CodiceTipoBeneRFI">
<column name="CodiceTipoBeneRFI" sql-type="smallint" not-null="true" />
</property>
<many-to-one name="TipiRame" update="false" insert="false">
<column name="CodiceTipoRame" sql-type="varchar" not-null="false" />
</many-to-one>
<property name="CodiceTipoRame">
<column name="CodiceTipoRame" sql-type="varchar" not-null="false" />
</property>
<many-to-one name="TipiUnitaMisura" update="false" insert="false">
<column name="CodiceTipoUnitaMisura" sql-type="tinyint" not-null="false" />
</many-to-one>
<property name="CodiceTipoUnitaMisura">
<column name="CodiceTipoUnitaMisura" sql-type="tinyint" not-null="false" />
</property>
</class>
</hibernate-mapping>
using System;
using System.Text;
using System.Collections.Generic;
using NHibernate.Proxy;
namespace Data.Model.Domain.Eventi
{
[Serializable]
public class EventiDettaglioBeneInteressato : Entity, IEntity
{
public virtual Eventi Evento { get; set; }
public virtual byte PrgOrdinamento { get; set; }
public virtual TipiBeneRFI TipiBeneRFI { get; set; }
public virtual TipiRame TipiRame { get; set; }
public virtual TipiUnitaMisura TipiUnitaMisura { get; set; }
public virtual short CodiceTipoBeneRFI { get; set; }
public virtual string CodiceTipoRame { get; set; }
public virtual byte? CodiceTipoUnitaMisura { get; set; }
public virtual string DescrizioneAltroBeneRFI { get; set; }
public virtual long? NumQuantita { get; set; }
#region NHibernate Composite Key Requirements
public override int GetHashCode()
{
unchecked
{
int hash = GetType().GetHashCode();
hash = (hash * 397) ^ PrgOrdinamento.GetHashCode();
hash = (hash * 397) ^ (Evento == null ? 0.GetHashCode() : Evento.GetHashCode());
return hash;
}
}
public override bool Equals(object obj)
{
return Equals(obj as EventiDettaglioBeneInteressato);
}
public virtual bool Equals(EventiDettaglioBeneInteressato other)
{
if (other == null)
{
return false;
}
if (ReferenceEquals(other, this))
{
return true;
}
var otherType = NHibernateProxyHelper.GetClassWithoutInitializingProxy(other);
var thisType = NHibernateProxyHelper.GetClassWithoutInitializingProxy(this);
if (!otherType.Equals(thisType))
{
return false;
}
bool otherIsTransient = Equals(other.Evento, null) && Equals(other.PrgOrdinamento, 0);
bool thisIsTransient = Equals(Evento, null) && Equals(PrgOrdinamento, 0);
if (otherIsTransient || thisIsTransient)
return false;
return Equals(other, this);
}
private bool Equals(EventiDettaglioBeneInteressato a, EventiDettaglioBeneInteressato b)
{
if (a.Evento == b.Evento
&& a.PrgOrdinamento == b.PrgOrdinamento)
return true;
return false;
}
#endregion
}
}
[TestMethod]
public void EventoTest_Add_Child_BeniInteressati()
{
var codiceEvento = "20140630_013325_BA";
using (var session = IoC.Container.Resolve<ISessionFactory>().OpenSession())
{
var evento = session.Get<Data.Model.Domain.Eventi.Eventi>(codiceEvento);
Assert.AreEqual(evento.EventiDettaglio.Count, 0);
var beneInteressato = new Data.Model.Domain.Eventi.EventiDettaglioBeneInteressato();
beneInteressato.PrgOrdinamento = 1;
beneInteressato.Evento = evento;
beneInteressato.CodiceTipoBeneRFI = 1;
evento.EventiDettaglio.Add(beneInteressato);
var beneInteressato2 = new Data.Model.Domain.Eventi.EventiDettaglioBeneInteressato();
beneInteressato.PrgOrdinamento = 2;
beneInteressato.Evento = evento;
beneInteressato.CodiceTipoBeneRFI = 2;
evento.EventiDettaglio.Add(beneInteressato2);
session.SaveOrUpdate(evento);
session.Flush();
}
}
Error:
Message:
Cannot insert the value NULL into column 'CodiceEvento', table 'Evento.EventiDettaglioBeneInteressato'; column does not allow nulls. INSERT fails.
The statement has been terminated.
StackTrace:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at System.Data.SqlClient.SqlCommand.ExecuteBatchRPCCommand()
at System.Data.SqlClient.SqlCommandSet.ExecuteNonQuery()
at NHibernate.AdoNet.SqlClientSqlCommandSet.ExecuteNonQuery()
at NHibernate.AdoNet.SqlClientBatchingBatcher.DoExecuteBatch(IDbCommand ps)
LOG:
18:15:25.695 [10] WARN NHibernate.Engine.ForeignKeys - Unable to determine if Data.Model.Domain.Eventi.EventiDettaglioBeneInteressato with assigned identifier Data.Model.Domain.Eventi.EventiDettaglioBeneInteressato is transient or detached; querying the database. Use explicit Save() or Update() in session to prevent this.
18:15:25.716 [10] WARN NHibernate.Engine.ForeignKeys - Unable to determine if Data.Model.Domain.Eventi.EventiDettaglioBeneInteressato with assigned identifier Data.Model.Domain.Eventi.EventiDettaglioBeneInteressato is transient or detached; querying the database. Use explicit Save() or Update() in session to prevent this.
18:15:25.960 [10] WARN NHibernate.Util.ADOExceptionReporter - System.Data.SqlClient.SqlException (0x80131904): Cannot insert the value NULL into column 'CodiceEvento', table 'Evento.EventiDettaglioBeneInteressato'; column does not allow nulls. INSERT fails.
The statement has been terminated.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at System.Data.SqlClient.SqlCommand.ExecuteBatchRPCCommand()
at System.Data.SqlClient.SqlCommandSet.ExecuteNonQuery()
at NHibernate.AdoNet.SqlClientSqlCommandSet.ExecuteNonQuery()
at NHibernate.AdoNet.SqlClientBatchingBatcher.DoExecuteBatch(IDbCommand ps)
ClientConnectionId:b0edabca-f2b9-4cc5-95b8-120653b5dc31
18:15:26.012 [10] ERROR NHibernate.Util.ADOExceptionReporter - Cannot insert the value NULL into column 'CodiceEvento', table 'Evento.EventiDettaglioBeneInteressato'; column does not allow nulls. INSERT fails.
The statement has been terminated.
18:15:26.047 [10] ERROR NHibernate.Event.Default.AbstractFlushingEventListener - Could not synchronize database state with session
NHibernate.Exceptions.GenericADOException: could not execute batch command.[SQL: SQL not available] ---> System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'CodiceEvento', table 'Evento.EventiDettaglioBeneInteressato'; column does not allow nulls. INSERT fails.
The statement has been terminated.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at System.Data.SqlClient.SqlCommand.ExecuteBatchRPCCommand()
at System.Data.SqlClient.SqlCommandSet.ExecuteNonQuery()
at NHibernate.AdoNet.SqlClientSqlCommandSet.ExecuteNonQuery()
at NHibernate.AdoNet.SqlClientBatchingBatcher.DoExecuteBatch(IDbCommand ps)
--- End of inner exception stack trace ---
at NHibernate.AdoNet.SqlClientBatchingBatcher.DoExecuteBatch(IDbCommand ps)
at NHibernate.AdoNet.AbstractBatcher.ExecuteBatchWithTiming(IDbCommand ps)
at NHibernate.AdoNet.AbstractBatcher.ExecuteBatch()
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
at NHibernate.Engine.ActionQueue.ExecuteActions()
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
[Test]
public void TestMethod()
{
var session = SessionFactory.OpenSession();
var codiceEvento = "20140630_013325_BA";
//Step1. Create a new Eventi to be saved with the given code
using (var trx = session.BeginTransaction())
{
var eventi = new Eventi
{
CodiceEvento = codiceEvento
};
session.SaveOrUpdate(eventi);
trx.Commit();
}
//Step2. Clear the session so the Eventi object have to be loaded again
session.Clear();
using (var trx = session.BeginTransaction())
{
var evento = session.Get<Eventi>(codiceEvento);
//assert the object has no child yet
evento.EventiDettaglio.Count().Should().Be(0);
//Step3. Add objects without specify the relationship
evento.Add(new EventiDettaglioBeneInteressato
{
PrgOrdinamento = 1,
CodiceTipoBeneRFI = 1
});
evento.Add(new EventiDettaglioBeneInteressato
{
PrgOrdinamento = 2,
CodiceTipoBeneRFI = 2
});
evento.Add(new EventiDettaglioBeneInteressato
{
PrgOrdinamento = 3,
CodiceTipoBeneRFI = 3
});
evento.Add(new EventiDettaglioBeneInteressato
{
PrgOrdinamento = 4,
CodiceTipoBeneRFI = 4
});
//Step4. save the root and then check if all the collection is saved
session.SaveOrUpdate(evento);
trx.Commit();
}
//Step5. clear again the session to make sure all the things are loaded well from db
session.Clear();
using (var trx = session.BeginTransaction())
{
var evento = session.Get<Eventi>(codiceEvento);
//Step6. load the root and then assert the child collection has 4 elements
evento.EventiDettaglio.Count().Should().Be(4);
//Step7. delete the root object to repeat the test again and test the cascade
session.Delete(evento);
trx.Commit();
}
//Step8. check there's no child object for that codiceEvento. the cascade is working!
using (var trx = session.BeginTransaction())
{
session.Query<EventiDettaglioBeneInteressato>()
.Count(it => it.Evento.CodiceEvento == codiceEvento)
.Should().Be(0);
trx.Commit();
}
}
[Serializable]
public class Eventi
{
private IList<EventiDettaglioBeneInteressato> _eventiDettaglio;
public Eventi()
{
_eventiDettaglio = new List<EventiDettaglioBeneInteressato>();
}
public virtual string CodiceEvento { get; set; }
public virtual string DescrizioneEvento { get; set; }
public virtual short CodiceTipoEvento { get; set; }
public virtual short? CodiceTipoAltroEvento { get; set; }
public virtual byte CodiceTipoClasseEvento { get; set; }
public virtual byte? CodiceTipoCausaEvento { get; set; }
public virtual byte CodiceTipoStatoSchedaEvento { get; set; }
public virtual int? CodiceGestoreAsset { get; set; }
public virtual byte? CodiceTipoOraEvento { get; set; }
public virtual short? CodiceTipoAutoreEvento { get; set; }
public virtual short? CodiceTipoSegnalazioneEvento { get; set; }
public virtual IEnumerable<EventiDettaglioBeneInteressato> EventiDettaglio { get { return _eventiDettaglio; } }
public virtual void Add(EventiDettaglioBeneInteressato dettaglioBeneInteressato)
{
dettaglioBeneInteressato.Evento = this;
_eventiDettaglio.Add(dettaglioBeneInteressato);
}
#region NHibernate Composite Key Requirements
public override bool Equals(object obj)
{
if (obj == null) return false;
var t = obj as Eventi;
if (t == null) return false;
if (CodiceEvento == t.CodiceEvento)
return true;
return false;
}
public override int GetHashCode()
{
int hash = GetType().GetHashCode();
hash = (hash * 397) ^ CodiceEvento.GetHashCode();
return hash;
}
#endregion
}
<hibernate-mapping assembly="MyOverFlow.Tests" namespace="MyOverFlow.Tests.NHibernate.Domain" xmlns="urn:nhibernate-mapping-2.2">
<class name="Eventi" table="Eventi" lazy="true" schema="Evento">
<id name="CodiceEvento" column="CodiceEvento" />
<property name="CodiceTipoEvento" >
<column name="CodiceTipoEvento" sql-type="smallint" not-null="true" />
</property>
<property name="CodiceTipoAltroEvento" >
<column name="CodiceTipoAltroEvento" sql-type="smallint" not-null="false" />
</property>
<property name="CodiceTipoClasseEvento">
<column name="CodiceTipoClasseEvento" sql-type="tinyint" not-null="true" />
</property>
<property name="CodiceTipoCausaEvento" >
<column name="CodiceTipoCausaEvento" sql-type="tinyint" />
</property>
<property name="CodiceTipoStatoSchedaEvento">
<column name="CodiceTipoStatoSchedaEvento" sql-type="tinyint" not-null="true" />
</property>
<property name="CodiceGestoreAsset">
<column name="CodiceGestoreAsset" sql-type="int" not-null="false" />
</property>
<property name="CodiceTipoOraEvento">
<column name="CodiceTipoOraEvento" sql-type="tinyint" not-null="false" />
</property>
<property name="CodiceTipoAutoreEvento">
<column name="CodiceTipoAutoreEvento" sql-type="smallint" not-null="false" />
</property>
<property name="CodiceTipoSegnalazioneEvento">
<column name="CodiceTipoSegnalazioneEvento" sql-type="smallint" not-null="false" />
</property>
<property name="DescrizioneEvento">
<column name="DescrizioneEvento" sql-type="varchar" not-null="false" />
</property>
<bag name="EventiDettaglio" table="EventiDettaglioBeneInteressato"
access="nosetter.camelcase-underscore"
schema="Evento" inverse="true" cascade="all-delete-orphan" >
<key column="CodiceEvento" />
<one-to-many class="EventiDettaglioBeneInteressato" />
</bag>
</class>
</hibernate-mapping>