-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 18 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Save a collection again after rollback
PostPosted: Sat Sep 16, 2006 12:06 am 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
I am using NHibernate on a Windows Application, using a single session with connect/disconnect approach. It works well until rolling back a transaction.

let's say object A has a collection of object B. We got a new object A with multiple new object B. we call Session.Save(objectA) but an exception is thrown. At this point, how should we recover and save the objectA (together with child objects B) ?

I tried to create a new Session and call Save(objectA) but got a NHibernate.AssertionFailure: no collection snapshot for orphan delete exception.

Hibernate version:
1.2.0

Mapping documents:
For simplicity, FitMeasure has a collection of FitMeasureSize
Code:
  <class name="Tti.Gos.BasicMaster.Common.FitMeasureSize, Tti.Gos.BasicMaster.Common" lazy="false" dynamic-update="true" dynamic-insert="true" table="FitMeasureSize">
    <id name="KeyId" unsaved-value="0">
      <generator class="Tti.Framework.DataAccess.NH.IdGenerator, Tti.Framework.DataAccess" />
    </id>
    <property name="SizeName" length="7" />
    <property name="SeqNo" />
    <many-to-one name="FitMeasure" access="NHibernate.Generics.GenericAccessor+CamelCase, NHibernate.Generics" class="Tti.Gos.BasicMaster.Common.FitMeasure, Tti.Gos.BasicMaster.Common" column="FitMeasureMasterKeyId" />
  </class>
  <class name="Tti.Gos.BasicMaster.Common.FitMeasure, Tti.Gos.BasicMaster.Common" lazy="false" dynamic-update="true" dynamic-insert="true" table="FitMeasureMaster">
    <id name="KeyId" unsaved-value="0">
      <generator class="Tti.Framework.DataAccess.NH.IdGenerator, Tti.Framework.DataAccess" />
    </id>
    <version name="Version" unsaved-value="0" />
    <property name="Description" length="60" />
    <property name="ModuleNo" column="FitName" length="10" />
    <property name="RecordStatus" />
    <property name="RecordStatusModifiedAt" type="NHibernate.Nullables2.NullableDateTimeType,NHibernate.Nullables2" />
    <property name="RecordStatusModifiedBy" type="NHibernate.Nullables2.NullableInt32Type,NHibernate.Nullables2" />
    <property name="CreatedAt" type="NHibernate.Nullables2.NullableDateTimeType,NHibernate.Nullables2" />
    <property name="CreatedBy" />
    <property name="LastModifiedAt" type="NHibernate.Nullables2.NullableDateTimeType,NHibernate.Nullables2" />
    <property name="LastModifiedBy" />
    <set name="FitMeasureSizes" access="NHibernate.Generics.GenericAccessor+CamelCase, NHibernate.Generics" lazy="false" cascade="all-delete-orphan" inverse="true" order-by="SeqNo">
      <key column="FitMeasureMasterKeyId" />
      <one-to-many class="Tti.Gos.BasicMaster.Common.FitMeasureSize, Tti.Gos.BasicMaster.Common" />
    </set>
  </class>


Code between sessionFactory.openSession() and session.close():
Code:
#line 1001
        public void TestNHibernate()
        {
            NHibernate.ISession session = null;

            // init business objects
            FitMeasure fitMeasure = GetNewFitMeasure();
            FitMeasureSize fitMeasureSize = GetNewFitMeasureSize();
            fitMeasure.FitMeasureSizes.Add(fitMeasureSize);

            // frist try
            session = Tti.Framework.DataAccess.NH.SessionManager.OpenSession();
            using (NHibernate.ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    session.Save(fitMeasure);
                    session.Flush();
                    transaction.Commit();
                }
                catch (NHibernate.ADOException e) // Violation of UNIQUE KEY constraint
                {
                    Console.WriteLine(e.ToString());
                    transaction.Rollback();
                    session.Close();
                    session = null;
                }
            }

            FixUniqueConstraintError(fitMeasure);

            // second try
            session = session ?? Tti.Framework.DataAccess.NH.SessionManager.OpenSession();
            using (NHibernate.ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    session.Save(fitMeasure);
                    session.Flush();
                    transaction.Commit();
                }
                catch (NHibernate.ADOException e) // NHibernate.AssertionFailure: no collection snapshot for orphan delete
                {
                    Console.WriteLine(e.ToString());
                    transaction.Rollback();
                    session.Close();
                    session = null;
                }
            }
        }


Full stack trace of any exception that occurs:
first try (which is expected)
Code:
NHibernate.ADOException: could not insert: [Tti.Gos.BasicMaster.Common.FitMeasure#39] ---> System.Data.SqlClient.SqlException: Violation of UNIQUE KEY constraint 'UQ_FitMeasureMaster'. Cannot insert duplicate key in object 'dbo.FitMeasureMaster'.
The statement has been terminated.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   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)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at NHibernate.Impl.BatcherImpl.ExecuteNonQuery(IDbCommand cmd) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\BatcherImpl.cs:line 208
   at NHibernate.Impl.NonBatchingBatcher.AddToBatch(Int32 expectedRowCount) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\NonBatchingBatcher.cs:line 34
   at NHibernate.Persister.Entity.SingleTableEntityPersister.Insert(Object id, Object[] fields, Boolean[] notNull, SqlString sql, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\SingleTableEntityPersister.cs:line 539
   --- End of inner exception stack trace ---
   at NHibernate.Persister.Entity.SingleTableEntityPersister.Insert(Object id, Object[] fields, Boolean[] notNull, SqlString sql, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\SingleTableEntityPersister.cs:line 549
   at NHibernate.Persister.Entity.SingleTableEntityPersister.Insert(Object id, Object[] fields, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\SingleTableEntityPersister.cs:line 492
   at NHibernate.Impl.ScheduledInsertion.Execute() in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\ScheduledInsertion.cs:line 38
   at NHibernate.Impl.SessionImpl.Execute(IExecutable executable) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 3163
   at NHibernate.Impl.SessionImpl.ExecuteAll(IList list) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 3142
   at NHibernate.Impl.SessionImpl.Execute() in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 3094
   at NHibernate.Impl.SessionImpl.Flush() in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 2930
   at Tti.Gos.BasicMaster.ClientService.Test.FitMeasureTest.TestNHibernate() in C:\Devel\Tti\Gos.Test\BasicMaster\Tti.Gos.BasicMaster.ClientService.Test\FitMeasureTest.cs:line 1017


second try (my problem)
Code:
NHibernate.ADOException: Could not save object ---> NHibernate.AssertionFailure: no collection snapshot for orphan delete
   at NHibernate.Impl.CollectionEntry.GetOrphans(Type entityName, IPersistentCollection collection) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\CollectionEntry.cs:line 423
   at NHibernate.Engine.Cascades.DeleteOrphans(Type entityName, IPersistentCollection pc, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 700
   at NHibernate.Engine.Cascades.CascadeCollection(CascadingAction action, CascadeStyle style, CollectionType collectionType, IType elemType, Object child, CascadePoint cascadeVia, ISessionImplementor session, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 690
   at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, Object child, IType type, CascadingAction action, CascadeStyle style, CascadePoint cascadeTo, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 582
   at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, IEntityPersister persister, Object parent, CascadingAction action, CascadePoint cascadeTo, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 641
   at NHibernate.Impl.SessionImpl.DoSave(Object theObj, EntityKey key, IEntityPersister persister, Boolean replicate, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 991
   at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IEntityPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 882
   at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 771
   --- End of inner exception stack trace ---
   at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 781
   at NHibernate.Impl.SessionImpl.Save(Object obj) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 718
   at Tti.Gos.BasicMaster.ClientService.Test.FitMeasureTest.TestNHibernate() in C:\Devel\Tti\Gos.Test\BasicMaster\Tti.Gos.BasicMaster.ClientService.Test\FitMeasureTest.cs:line 1037


Name and version of the database you are using:
MS SQL Server 2005

The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:


Problems with Session and transaction handling?

Read this: http://hibernate.org/42.html


Top
 Profile  
 
 Post subject: 2 Sessions ! and 1 Cascade
PostPosted: Tue Sep 19, 2006 3:22 am 
Regular
Regular

Joined: Mon Aug 28, 2006 6:35 am
Posts: 66
Location: Middle East
Dear canton,

Try to remove the cascade="delete-all-orphan" from your mapping files !
Why you are using 2 sessions ? 1 Session would do the job ..

Hope that it solved your problem ...

Regards,
Jojorico

_________________
In Code We Trust


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 19, 2006 6:55 am 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
Dear Jojorico,

Thanks for your reply.

The code in my first message is not production code. It was written to illustrate the problem: How shoud I recover from a exception during Save()? I tried to create a second Session instance and Save() again but a strange exception was thrown.

I created the second Session instance because I had to discard the first Session instance after I caught an exception. (Ref: http://www.hibernate.org/hib_docs/nhibernate/html/manipulatingdata.html#manipulatingdata-exceptions)

If i remove cascade="delete-all-orphan", I will have to manage the life cycles of all business objects myself by Interceptor. I hope I would find another solution before removing "delete-all-orphan" because I have very complex object graphs here. It will be painful if I have to Delete()/Save() them one by one.

This should not be a rare problem. Anyone has encountered/solved it?

Regards,

Canton


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 19, 2006 12:23 pm 
Regular
Regular

Joined: Mon Aug 28, 2006 6:35 am
Posts: 66
Location: Middle East
Dear Canton,

I'm not using the IInterceptor in my application ...
And by the way, i was having a lot of problems while using the cascade=delete-all-orphan such as the exception having a message similar to this :
Cannot Open Session -- Using 2 sessions on the same object .. somethin like that although i was only opening 1 session in the DA layer ..
And i was getting an exception when trying to set the Hibernate Manager Class Constructor as static ...

So i surfed the web and i've got a hint to use cascade="none" instead of the cascade="delete-all-orphan"... so i did

I don't know if these information were useful for you but i hope so

Regards,
Jojo

_________________
In Code We Trust


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 20, 2006 11:41 pm 
Regular
Regular

Joined: Mon Aug 28, 2006 6:35 am
Posts: 66
Location: Middle East
Dear Canton,

I hope to here from you soon and to know what's going on with you...

Regards,
Jojo

_________________
In Code We Trust


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 21, 2006 12:08 am 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
Jojo,

My system here relies on cascade="delete-all-orphan" heavily so switching to cascade="none" would not be easy. so I will leave it as a last resort.

What I want to know is whether the exception "NHibernate.AssertionFailure: no collection snapshot for orphan delete" is a *normal* behavior when using cascade="delete-all-orphan". If it is, I will try some workarounds. If not, I will rather wait for the fix.

Thanks for you help. I am sad that no other is replying :(. I will try to create a small project to simulate the problem.

Regards,
Canton


Top
 Profile  
 
 Post subject: I might Help
PostPosted: Thu Sep 21, 2006 4:34 am 
Regular
Regular

Joined: Mon Aug 28, 2006 6:35 am
Posts: 66
Location: Middle East
Dear Canton,

I'm doing my best to help... bby the way, some of your problems faced me and or is facing me ... so we both get benefits from other ...
I'll focus on this matter on this weekend so if you can provide me with a mapping file of yours and c# class declaration .. that might help.

Regards,
JojoRico

_________________
In Code We Trust


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 22, 2006 3:21 am 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
Dear Jojo,

Thanks very much. I have created a very simple project to demostrate the problem. You can download it here http://www.box.net/public/r4czvjy32i. It contains the project source code and a SetupTables.sql file to create necessary tables in the database.

I am using SQL2005, Visual Studio 2005, NHibernate 1.2.0 alpha 1.

This is the output i found in Log\demo.txt
Code:
15:18:21.482 [2868] INFO  DemoLog - Insert first order ...
15:18:21.685 [2868] INFO  DemoLog - Insert first order done.
15:18:21.685 [2868] INFO  DemoLog - ********************
15:18:21.685 [2868] INFO  DemoLog - Insert second order ...
15:18:21.716 [2868] ERROR DemoLog - Insert Error
NHibernate.ADOException: could not insert: [OrphanDeleteSample.Order] ---> System.Data.SqlClient.SqlException: Violation of UNIQUE KEY constraint 'IX_Order_OrderNo'. Cannot insert duplicate key in object 'dbo.Order'.
The statement has been terminated.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   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)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
   at NHibernate.Impl.BatcherImpl.ExecuteReader(IDbCommand cmd) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\BatcherImpl.cs:line 224
   at NHibernate.Persister.Entity.AbstractEntityPersister.InsertImpl(Object[] fields, Boolean[] notNull, SqlString sql, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 1771
   --- End of inner exception stack trace ---
   at NHibernate.Persister.Entity.AbstractEntityPersister.InsertImpl(Object[] fields, Boolean[] notNull, SqlString sql, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 1815
   at NHibernate.Persister.Entity.SingleTableEntityPersister.Insert(Object[] fields, Boolean[] notNull, SqlString sql, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\SingleTableEntityPersister.cs:line 564
   at NHibernate.Persister.Entity.SingleTableEntityPersister.Insert(Object[] fields, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\SingleTableEntityPersister.cs:line 483
   at NHibernate.Impl.ScheduledIdentityInsertion.Execute() in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\ScheduledIdentityInsertion.cs:line 38
   at NHibernate.Impl.SessionImpl.Execute(IExecutable executable) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 3163
   at NHibernate.Impl.SessionImpl.DoSave(Object theObj, EntityKey key, IEntityPersister persister, Boolean replicate, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 970
   at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IEntityPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 882
   at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 777
   at NHibernate.Impl.SessionImpl.Save(Object obj) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 718
   at OrphanDeleteSample.OrderService.Insert(Order order) in C:\Devel\OrphanDeleteSample\OrderService.cs:line 55
15:18:21.732 [2868] INFO  DemoLog - Insert second order done.
15:18:21.732 [2868] INFO  DemoLog - ********************
15:18:21.732 [2868] INFO  DemoLog - Insert second order after ...
15:18:21.732 [2868] ERROR DemoLog - Insert Error
NHibernate.ADOException: Could not save object ---> NHibernate.AssertionFailure: no collection snapshot for orphan delete
   at NHibernate.Impl.CollectionEntry.GetOrphans(Type entityName, IPersistentCollection collection) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\CollectionEntry.cs:line 423
   at NHibernate.Engine.Cascades.DeleteOrphans(Type entityName, IPersistentCollection pc, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 700
   at NHibernate.Engine.Cascades.CascadeCollection(CascadingAction action, CascadeStyle style, CollectionType collectionType, IType elemType, Object child, CascadePoint cascadeVia, ISessionImplementor session, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 690
   at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, Object child, IType type, CascadingAction action, CascadeStyle style, CascadePoint cascadeTo, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 582
   at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, IEntityPersister persister, Object parent, CascadingAction action, CascadePoint cascadeTo, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 641
   at NHibernate.Impl.SessionImpl.DoSave(Object theObj, EntityKey key, IEntityPersister persister, Boolean replicate, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 991
   at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IEntityPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 882
   at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 763
   --- End of inner exception stack trace ---
   at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 781
   at NHibernate.Impl.SessionImpl.Save(Object obj) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 718
   at OrphanDeleteSample.OrderService.Insert(Order order) in C:\Devel\OrphanDeleteSample\OrderService.cs:line 55
15:18:21.732 [2868] INFO  DemoLog - Insert second order after fix done.


and in general.txt
Code:
15:18:20.747 [2868] INFO  NHibernate.Cfg.Environment - NHibernate 1.2.0.1001 (1.2.0.Alpha1)
15:18:20.763 [2868] INFO  NHibernate.Cfg.Environment - Bytecode provider name : lcg
15:18:20.763 [2868] INFO  NHibernate.Cfg.Environment - Using reflection optimizer
15:18:20.779 [2868] INFO  NHibernate.Cfg.Configuration - Found mapping documents in assembly: OrphanDeleteSample.Order.hbm.xml
15:18:20.857 [2868] INFO  NHibernate.Dialect.Dialect - Using dialect: NHibernate.Dialect.MsSql2005Dialect
15:18:20.888 [2868] INFO  NHibernate.Cfg.HbmBinder - Mapping class: OrphanDeleteSample.Order -> Order
15:18:20.966 [2868] INFO  NHibernate.Cfg.Configuration - Found mapping documents in assembly: OrphanDeleteSample.OrderItem.hbm.xml
15:18:20.966 [2868] INFO  NHibernate.Dialect.Dialect - Using dialect: NHibernate.Dialect.MsSql2005Dialect
15:18:20.982 [2868] INFO  NHibernate.Cfg.HbmBinder - Mapping class: OrphanDeleteSample.OrderItem -> OrderItem
15:18:20.982 [2868] INFO  NHibernate.Cfg.Configuration - processing one-to-many association mappings
15:18:20.997 [2868] INFO  NHibernate.Cfg.HbmBinder - mapping collection: OrphanDeleteSample.Order.OrderItems -> OrderItem
15:18:20.997 [2868] INFO  NHibernate.Cfg.Configuration - processing one-to-one association property references
15:18:20.997 [2868] INFO  NHibernate.Cfg.Configuration - processing foreign key constraints
15:18:21.013 [2868] INFO  NHibernate.Dialect.Dialect - Using dialect: NHibernate.Dialect.MsSql2005Dialect
15:18:21.013 [2868] INFO  NHibernate.Connection.ConnectionProviderFactory - Intitializing connection provider: NHibernate.Connection.DriverConnectionProvider
15:18:21.013 [2868] INFO  NHibernate.Connection.ConnectionProvider - Configuring ConnectionProvider
15:18:21.013 [2868] INFO  NHibernate.Cfg.SettingsFactory - Optimize cache for minimal puts: False
15:18:21.013 [2868] INFO  NHibernate.Cfg.SettingsFactory - Default schema set to: dbo
15:18:21.029 [2868] INFO  NHibernate.Cfg.SettingsFactory - Query language substitutions: {}
15:18:21.029 [2868] INFO  NHibernate.Cfg.SettingsFactory - cache provider: NHibernate.Cache.HashtableCacheProvider
15:18:21.029 [2868] INFO  NHibernate.Cfg.Configuration - instantiating and configuring caches
15:18:21.029 [2868] INFO  NHibernate.Impl.SessionFactoryImpl - building session factory
15:18:21.185 [2868] INFO  NHibernate.Impl.SessionFactoryObjectFactory - no name configured
15:18:21.482 [2868] INFO  DemoLog - Insert first order ...
15:18:21.685 [2868] INFO  DemoLog - Insert first order done.
15:18:21.685 [2868] INFO  DemoLog - ********************
15:18:21.685 [2868] INFO  DemoLog - Insert second order ...
15:18:21.685 [2868] WARN  NHibernate.Util.ADOExceptionReporter - System.Data.SqlClient.SqlException: Violation of UNIQUE KEY constraint 'IX_Order_OrderNo'. Cannot insert duplicate key in object 'dbo.Order'.
The statement has been terminated.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   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)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
   at NHibernate.Impl.BatcherImpl.ExecuteReader(IDbCommand cmd) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\BatcherImpl.cs:line 224
   at NHibernate.Persister.Entity.AbstractEntityPersister.InsertImpl(Object[] fields, Boolean[] notNull, SqlString sql, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 1771
15:18:21.716 [2868] ERROR NHibernate.Util.ADOExceptionReporter - Violation of UNIQUE KEY constraint 'IX_Order_OrderNo'. Cannot insert duplicate key in object 'dbo.Order'.
The statement has been terminated.
15:18:21.716 [2868] ERROR DemoLog - Insert Error
NHibernate.ADOException: could not insert: [OrphanDeleteSample.Order] ---> System.Data.SqlClient.SqlException: Violation of UNIQUE KEY constraint 'IX_Order_OrderNo'. Cannot insert duplicate key in object 'dbo.Order'.
The statement has been terminated.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   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)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
   at NHibernate.Impl.BatcherImpl.ExecuteReader(IDbCommand cmd) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\BatcherImpl.cs:line 224
   at NHibernate.Persister.Entity.AbstractEntityPersister.InsertImpl(Object[] fields, Boolean[] notNull, SqlString sql, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 1771
   --- End of inner exception stack trace ---
   at NHibernate.Persister.Entity.AbstractEntityPersister.InsertImpl(Object[] fields, Boolean[] notNull, SqlString sql, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 1815
   at NHibernate.Persister.Entity.SingleTableEntityPersister.Insert(Object[] fields, Boolean[] notNull, SqlString sql, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\SingleTableEntityPersister.cs:line 564
   at NHibernate.Persister.Entity.SingleTableEntityPersister.Insert(Object[] fields, Object obj, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Persister\Entity\SingleTableEntityPersister.cs:line 483
   at NHibernate.Impl.ScheduledIdentityInsertion.Execute() in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\ScheduledIdentityInsertion.cs:line 38
   at NHibernate.Impl.SessionImpl.Execute(IExecutable executable) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 3163
   at NHibernate.Impl.SessionImpl.DoSave(Object theObj, EntityKey key, IEntityPersister persister, Boolean replicate, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 970
   at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IEntityPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 882
   at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 777
   at NHibernate.Impl.SessionImpl.Save(Object obj) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 718
   at OrphanDeleteSample.OrderService.Insert(Order order) in C:\Devel\OrphanDeleteSample\OrderService.cs:line 55
15:18:21.732 [2868] INFO  DemoLog - Insert second order done.
15:18:21.732 [2868] INFO  DemoLog - ********************
15:18:21.732 [2868] INFO  DemoLog - Insert second order after ...
15:18:21.732 [2868] ERROR NHibernate.AssertionFailure - An AssertionFailure occured - this may indicate a bug in NHibernate
NHibernate.AssertionFailure: no collection snapshot for orphan delete
15:18:21.732 [2868] WARN  NHibernate.Util.ADOExceptionReporter - NHibernate.AssertionFailure: no collection snapshot for orphan delete
   at NHibernate.Impl.CollectionEntry.GetOrphans(Type entityName, IPersistentCollection collection) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\CollectionEntry.cs:line 423
   at NHibernate.Engine.Cascades.DeleteOrphans(Type entityName, IPersistentCollection pc, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 700
   at NHibernate.Engine.Cascades.CascadeCollection(CascadingAction action, CascadeStyle style, CollectionType collectionType, IType elemType, Object child, CascadePoint cascadeVia, ISessionImplementor session, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 690
   at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, Object child, IType type, CascadingAction action, CascadeStyle style, CascadePoint cascadeTo, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 582
   at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, IEntityPersister persister, Object parent, CascadingAction action, CascadePoint cascadeTo, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 641
   at NHibernate.Impl.SessionImpl.DoSave(Object theObj, EntityKey key, IEntityPersister persister, Boolean replicate, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 991
   at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IEntityPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 882
   at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 763
15:18:21.732 [2868] ERROR NHibernate.Util.ADOExceptionReporter - no collection snapshot for orphan delete
15:18:21.732 [2868] ERROR DemoLog - Insert Error
NHibernate.ADOException: Could not save object ---> NHibernate.AssertionFailure: no collection snapshot for orphan delete
   at NHibernate.Impl.CollectionEntry.GetOrphans(Type entityName, IPersistentCollection collection) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\CollectionEntry.cs:line 423
   at NHibernate.Engine.Cascades.DeleteOrphans(Type entityName, IPersistentCollection pc, ISessionImplementor session) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 700
   at NHibernate.Engine.Cascades.CascadeCollection(CascadingAction action, CascadeStyle style, CollectionType collectionType, IType elemType, Object child, CascadePoint cascadeVia, ISessionImplementor session, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 690
   at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, Object child, IType type, CascadingAction action, CascadeStyle style, CascadePoint cascadeTo, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 582
   at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, IEntityPersister persister, Object parent, CascadingAction action, CascadePoint cascadeTo, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Engine\Cascades.cs:line 641
   at NHibernate.Impl.SessionImpl.DoSave(Object theObj, EntityKey key, IEntityPersister persister, Boolean replicate, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 991
   at NHibernate.Impl.SessionImpl.DoSave(Object obj, Object id, IEntityPersister persister, Boolean useIdentityColumn, CascadingAction cascadeAction, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 882
   at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 763
   --- End of inner exception stack trace ---
   at NHibernate.Impl.SessionImpl.SaveWithGeneratedIdentifier(Object obj, CascadingAction action, Object anything) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 781
   at NHibernate.Impl.SessionImpl.Save(Object obj) in c:\net\nhibernate\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 718
   at OrphanDeleteSample.OrderService.Insert(Order order) in C:\Devel\OrphanDeleteSample\OrderService.cs:line 55
15:18:21.732 [2868] INFO  DemoLog - Insert second order after fix done.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 22, 2006 3:58 am 
Beginner
Beginner

Joined: Wed Aug 10, 2005 6:21 pm
Posts: 24
Location: Antwerp, Belgium
canton,

if you want to get Sergey's or one of the others' attention, your best bet is to
create a Jira issue. You've already done most of the hard work (i.e. create a small stand alone project that demonstrates the issue) so you're almost there :-)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 22, 2006 4:07 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
I'm afraid I won't be able to help with this much since you're misusing NHibernate here. If there's an exception when using a session, you need to close it and you can't use the related objects neither.

The only workaround for you that I can see is to use some other cascade setting.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 22, 2006 6:22 am 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
Thanks for all of you.

Does that mean I have to implement ILifecycle if I change to cascade="none"? I don't want to misuse NHibernate again :)

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 26, 2006 3:51 am 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
I tried Cascade="none" together with ILifeCycle but I experienced another problem.


What I did are first to change
Code:
cascade="all-delete-orphan"
to
Code:
cascade="none"


Secondly, make Order class implement ILifeCycle. Here is the OnSave()
Code:
public LifecycleVeto OnSave(ISession s)
{
    foreach (OrderItem item in orderItems)
    {
        s.Save(item);
    }

    return LifecycleVeto.NoVeto;
}


Thirdly new instances of business objects (Order and OrderItem) were created after the exception.

Source code here: http://www.box.net/public/y8j0pefo0i


Though I managed to make the object persisted in database, the SQL statements generated were a bit strange. Specifically I am talking about the sequence of SQL statements.

OrderItem instances were inserted BEFORE Order instance. But I expect the sequence to be reversed. Am I making a mistake in OnSave()?

I got them from Profiler
Code:
exec sp_executesql N'INSERT INTO dbo.OrderItem (Price, Qty, OrderId, ItemNo) VALUES (@p0, @p1, @p2, @p3); select SCOPE_IDENTITY()',N'@p0
float,@p1 int,@p2 int,@p3 nvarchar(4000)',@p0=14.9,@p1=3,@p2=NULL,@p3=N'GE0234'
go
exec sp_executesql N'INSERT INTO dbo.OrderItem (Price, Qty, OrderId, ItemNo) VALUES (@p0, @p1, @p2, @p3); select SCOPE_IDENTITY()',N'@p0
float,@p1 int,@p2 int,@p3 nvarchar(4000)',@p0=30,@p1=1,@p2=NULL,@p3=N'GE0235'
go
exec sp_executesql N'INSERT INTO dbo.[Order] (CustomerName, OrderNo) VALUES (@p0, @p1); select SCOPE_IDENTITY()',N'@p0 nvarchar(4000),@p1
nvarchar(4000)',@p0=N'canton',@p1=N'WTF001'
go
exec sp_executesql N'UPDATE dbo.OrderItem SET Price = @p0, Qty = @p1, OrderId = @p2, ItemNo = @p3 WHERE Id = @p4',N'@p0 float,@p1 int,@p2
int,@p3 nvarchar(4000),@p4 int',@p0=14.9,@p1=3,@p2=48,@p3=N'GE0234',@p4=1
go
exec sp_executesql N'UPDATE dbo.OrderItem SET Price = @p0, Qty = @p1, OrderId = @p2, ItemNo = @p3 WHERE Id = @p4',N'@p0 float,@p1 int,@p2
int,@p3 nvarchar(4000),@p4 int',@p0=30,@p1=1,@p2=48,@p3=N'GE0235',@p4=2
go



I tried setting id generator to something other than "identity" (e.g. "increment" for a simple experiment) but still OrderItem was inserted before Order. Any clues?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 26, 2006 7:26 pm 
Beginner
Beginner

Joined: Wed Jun 01, 2005 3:22 pm
Posts: 38
Location: Menlo Park, CA
If there's an exception, something's borken and you're in an undefined state. 99% of the time, it's not worth the effort to even try and recover. You rollback to keep the database clean, log the exception so someone can fix the underlying problem, and apologize to the user.

If you really, truly, absolutley have to be able to recover from exceptions on Save, then the only safe way to do it is

1) throw away your old session and old object
2) open a new session
3) re-load your object from the database
4) re-apply your changes to the object
5) try the save again

Obviously, this will be a lot more work than simply try { saveorupdate } catch { saveorupdate again }.

I'm not 100% sure I'm right on this. YMMV.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 26, 2006 10:18 pm 
Regular
Regular

Joined: Tue Aug 08, 2006 4:28 am
Posts: 96
Location: Hong Kong
So I am in the 1%.

Here is my scenario.

I have an unique constraint on a column (call it ColumnA) in a database table.

checking is done before INSERT/UPDATE, like this
Code:
SELECT COUNT(*) FROM [Table] WHERE [ColumnA] = :userInputValue


But that is not enough when multiple users are trying to INSERT/UPDATE their records.

I can think of 2 solutions. 1 is to lock the entire table before the checking. Another is to catch the exception, and let user input another value. I chose the second approach.

From NHibernate doc, I know that I need to do step 2: "open a new session". But it does not tell I need to do step 3 "re-load object from database". Thanks sergey and rponton for telling me this.

Later on, I found that I don't need to re-load object from database if I changed cascade="all-delete-orphan" to cascade="none" and implement ILifeCycle instead. It is a good news to me (reconstructing the objects is pain)

However, the sequence of INSERT statements is strange after using ILifeCycle. please note that the strangeness has nothing related to "recover" or "identity generator". Any clues?

Sorry for the lone thread and thanks for reading.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 01, 2006 8:22 pm 
Newbie

Joined: Sat Sep 23, 2006 5:23 pm
Posts: 3
I'm also in that 1%.

Have you tried the approach described here?

http://forum.hibernate.org/viewtopic.php?t=964268

1) Create an ISession
2) Manipulate some business domain objects
3) Serialize the ISession
4) Commit/Flush the changes to the db
5) If an exception occurs, restore the ISession from it's serialized state (so that I don't lose the ISession's contents)

I think the problem he was having was that the Session and associated objects are different instances than the ones he had before deserializing. If I get the object identifier (GetIdentifier) before I attempt to flush, I can retrieve it from the session afterwards (Get) and things seem to work normally afterwards.

I'm not sure yet if I think this is a good idea.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.