-->
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.  [ 7 posts ] 
Author Message
 Post subject: NHibernate is Updating my collection instead of inserting it
PostPosted: Thu Mar 16, 2006 10:23 pm 
Newbie

Joined: Thu Mar 16, 2006 10:07 pm
Posts: 3
Location: New Zealand
I have a class that has a collection of objects (which is a one to many relation); in the table they reference each other using composite keys... Everytime I go to save it to the database it inserts everything but comes to this collection and tries to update it.

The only difference between the two collections is that the one having a problem is a super class (inherits from a base class/table), references in the table are composite and the collection objects also reference another object.

Any info will be greatly appreciated,


Mapping documents:

My Main class references Training Unit Standard
<!-- Mapping for UnitStandards - Unit_Standards_Version -->
<bag name="UnitStandards" cascade="all-delete-orphan">
<key column="Training_ID" />
<one-to-many class="SITO.Entity.TrainingUnitStandard, SITO.Entity" />
</bag>
<!-- End of: Mapping for UnitStandards - Unit_Standards_Version -->

The Training Unit Standards mapping...
<!-- Mapping for TrainingUnitStandardBase - Training_Unit_Standard -->
<class name="SITO.Entity.TrainingUnitStandardBase, SITO.Entity" table="Training_Unit_Standard">
<composite-id>
<key-property name="TrainingID" column="Training_ID" />
<key-many-to-one name="Unit" column="Unit_Standard_ID" class="SITO.Entity.UnitStandardVersion, SITO.Entity" />
</composite-id>

<!-- Mapping for TrainingUnitStandard - Training_Unit_Standard_Details -->
<joined-subclass name="SITO.Entity.TrainingUnitStandard, SITO.Entity" table="Training_Unit_Standard_Details">
<key>
<column name="Training_ID" />
<column name="Unit_Standard_ID" />
</key>

<!-- pass the status code to the view so it can decide weather to store it in the temp table or permant table
or query the training table to see what the status is (since it is not inherited by the training class -->
<property name="MaxTrainees" column="Maximum_No_Of_Trainees" type="Nullables.NHibernate.NullableInt16Type, Nullables.NHibernate" />
<many-to-one name="AssessmentAccreditationCode" column="Assessment_Accreditation_Code" class="SITO.Entity.Lookup, SITO.Entity" />

</joined-subclass>
<!-- End of: Mapping for TrainingUnitStandard - Training_Unit_Standard_Details -->
</class>
<!-- End of: Mapping for TrainingUnitStandardBase - Training_Unit_Standard -->

Full stack trace of any exception that occurs:


The generated SQL (show_sql=true):
exec sp_executesql N'INSERT INTO Training (Training_Status_Code, Branch_Contact_Person_ID, Branch_ID, Training_Type_Code, Training_Reference) VALUES (@p0, @p1, @p2, @p3, @p4); select SCOPE_IDENTITY()', N'@p0 smallint,@p1 int,@p2 int,@p3 smallint,@p4 nvarchar(4000)', @p0 = 1091, @p1 = 6, @p2 = 3, @p3 = 0, @p4 = N'23434'

exec sp_executesql N'INSERT INTO v_Training_Details (Approved_Date, Company_Signed_Date, Company_Signed, Date_Completed, Estimated_Start_Date, SITO_Account_Code, SITO_Signed, Date_Terminated, Create_Date, Training_Status_Code, Estimated_End_Date, Training_ID) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11)', N'@p0 datetime,@p1 datetime,@p2 tinyint,@p3 datetime,@p4 datetime,@p5 int,@p6 tinyint,@p7 datetime,@p8 datetime,@p9 smallint,@p10 datetime,@p11 int', @p0 = 'Mar 17 2006 12:00:00:000AM', @p1 = NULL, @p2 = 0, @p3 = NULL, @p4 = 'Mar 17 2006 12:00:00:000AM', @p5 = 234, @p6 = 1, @p7 = NULL, @p8 = 'Mar 17 2006 12:00:00:000AM', @p9 = 1091, @p10 = 'May 20 2006 12:00:00:000AM', @p11 = 120

exec sp_executesql N'INSERT INTO Training_Schedule (Training_Provider_ID, Training_Provider_Contact_Person_ID, Training_ID) VALUES (@p0, @p1, @p2)', N'@p0 int,@p1 int,@p2 int', @p0 = 7, @p1 = 6, @p2 = 120

exec sp_executesql N'INSERT INTO v_Training_Schedule_Details (Other_SITO_Contribution, TP_Maximum_Fee, TP_Minimum_Fee, Other_Company_Contribution, Company_Contribution, Est_Total_Other_Costs, SITO_Contribution, NZQA_Admin_Fee, Minimum_No_Trainees, Training_Status_Code, Training_ID) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10)', N'@p0 decimal(19,5),@p1 decimal(19,5),@p2 decimal(19,5),@p3 decimal(19,5),@p4 decimal(19,5),@p5 decimal(19,5),@p6 decimal(19,5),@p7 decimal(19,5),@p8 int,@p9 smallint,@p10 int', @p0 = 40.00000, @p1 = 4440.00000, @p2 = 230.00000, @p3 = 40.00000, @p4 = 4000.00000, @p5 = 40.00000, @p6 = 440.00000, @p7 = 40.00000, @p8 = 23, @p9 = 1091, @p10 = 120

exec sp_executesql N'INSERT INTO Training_Other_Cost (Training_ID, Other_Cost_Code) VALUES (@p0, @p1); select SCOPE_IDENTITY()', N'@p0 int,@p1 smallint', @p0 = 120, @p1 = 9994

exec sp_executesql N'INSERT INTO Training_Other_Cost (Training_ID, Other_Cost_Code) VALUES (@p0, @p1); select SCOPE_IDENTITY()', N'@p0 int,@p1 smallint', @p0 = 120, @p1 = 9995

exec sp_executesql N'UPDATE Training_Unit_Standard_Details SET Assessment_Accreditation_Code = @p0, Maximum_No_Of_Trainees = @p1 WHERE Training_ID = @p2 AND Unit_Standard_ID = @p3', N'@p0 smallint,@p1 smallint,@p2 int,@p3 int', @p0 = 1103, @p1 = 12, @p2 = 0, @p3 = 2

Why is it UPDATING???

Debug level Hibernate log excerpt:

2006-03-17 15:14:14,107 [2888] DEBUG NHibernate.Persister.NormalizedEntityPersister - Updating entity: [SITO.Entity.TrainingUnitStandard#SITO.Entity.TrainingUnitStandard]
2006-03-17 15:14:14,107 [2888] DEBUG NHibernate.Impl.BatcherImpl - Opened new IDbCommand, open IDbCommands :1
2006-03-17 15:14:14,107 [2888] DEBUG NHibernate.Impl.BatcherImpl - Building an IDbCommand object for the SqlString: UPDATE Training_Unit_Standard_Details SET Assessment_Accreditation_Code = :Assessment_Accreditation_Code, Maximum_No_Of_Trainees = :Maximum_No_Of_Trainees WHERE Training_ID = :Training_ID AND Unit_Standard_ID = :Unit_Standard_ID
2006-03-17 15:14:14,107 [2888] DEBUG NHibernate.Persister.NormalizedEntityPersister - Dehydrating entity: SITO.Entity.TrainingUnitStandard#SITO.Entity.TrainingUnitStandard
2006-03-17 15:14:14,107 [2888] DEBUG NHibernate.Engine.Cascades - unsaved-value strategy NULL
2006-03-17 15:14:14,107 [2888] DEBUG NHibernate.Engine.Cascades - unsaved-value: 0
2006-03-17 15:14:14,107 [2888] DEBUG NHibernate.SQL - UPDATE Training_Unit_Standard_Details SET Assessment_Accreditation_Code = @p0, Maximum_No_Of_Trainees = @p1 WHERE Training_ID = @p2 AND Unit_Standard_ID = @p3
2006-03-17 15:14:14,107 [2888] ERROR NHibernate.StaleObjectStateException - An operation failed due to stale data
NHibernate.StaleObjectStateException: Row was updated or deleted by another transaction for SITO.Entity.TrainingUnitStandard instance with identifier: SITO.Entity.TrainingUnitStandard
2006-03-17 15:14:14,123 [2888] DEBUG NHibernate.Impl.BatcherImpl - Closed IDbCommand, open IDbCommands :0
2006-03-17 15:14:14,139 [2888] ERROR NHibernate.Impl.SessionImpl - could not synchronize database state with session
NHibernate.StaleObjectStateException: Row was updated or deleted by another transaction for SITO.Entity.TrainingUnitStandard instance with identifier: SITO.Entity.TrainingUnitStandard
at NHibernate.Persister.AbstractEntityPersister.Check(Int32 rows, Object id) in D:\SITO\SITO\Framework\NHibernate\Persister\AbstractEntityPersister.cs:line 545
at NHibernate.Persister.NormalizedEntityPersister.Update(Object id, Object[] fields, Boolean[] includeProperty, Boolean[] includeTable, Object oldVersion, Object obj, SqlString[] sql, ISessionImplementor session) in D:\SITO\SITO\Framework\NHibernate\Persister\NormalizedEntityPersister.cs:line 953
at NHibernate.Persister.NormalizedEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Object[] oldFields, Object oldVersion, Object obj, ISessionImplementor session) in D:\SITO\SITO\Framework\NHibernate\Persister\NormalizedEntityPersister.cs:line 894
at NHibernate.Impl.ScheduledUpdate.Execute() in D:\SITO\SITO\Framework\NHibernate\Impl\ScheduledUpdate.cs:line 54
at NHibernate.Impl.SessionImpl.Execute(IExecutable executable) in d:\sito\sito\framework\nhibernate\impl\sessionimpl.cs:line 3065
at NHibernate.Impl.SessionImpl.ExecuteAll(IList list) in d:\sito\sito\framework\nhibernate\impl\sessionimpl.cs:line 3044
at NHibernate.Impl.SessionImpl.Execute() in d:\sito\sito\framework\nhibernate\impl\sessionimpl.cs:line 2987
2006-03-17 15:14:14,139 [2888] DEBUG NHibernate.Transaction.AdoTransaction - rollback
2006-03-17 15:14:14,139 [2888] DEBUG NHibernate.Transaction.AdoTransaction - running AdoTransaction.Dispose()
2006-03-17 15:14:14,139 [2888] DEBUG NHibernate.Impl.SessionImpl - transaction completion
2006-03-17 15:14:14,170 [2888] DEBUG NHibernate.Impl.SessionImpl - closing session
2006-03-17 15:14:14,170 [2888] DEBUG NHibernate.Impl.SessionImpl - disconnecting session
2006-03-17 15:14:14,170 [2888] DEBUG NHibernate.Connection.ConnectionProvider - Closing connection
2006-03-17 15:14:14,170 [2888] DEBUG NHibernate.Impl.SessionImpl - transaction completion


Top
 Profile  
 
 Post subject: Re: NHibernate is Updating my collection instead of insertin
PostPosted: Fri Mar 17, 2006 4:08 am 
Expert
Expert

Joined: Thu Jan 19, 2006 4:29 pm
Posts: 348
newms wrote:
I have a class that has a collection of objects (which is a one to many relation); in the table they reference each other using composite keys... Everytime I go to save it to the database it inserts everything but comes to this collection and tries to update it.

The only difference between the two collections is that the one having a problem is a super class (inherits from a base class/table), references in the table are composite and the collection objects also reference another object.

Any info will be greatly appreciated,



AFAIK NH has some troubles to dtermine if object with composite key is unsaved or not. My personal suggestion is to not use composite (primary) keys - at least if You can alter database schema.

I have not used composite keys, so someone correct me if I'm wrong:
adding unsavedvalue="any" to key might help. Just remember that SaveOrUpdate will not work sensibly for those objects.

Gert


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 17, 2006 11:22 am 
Senior
Senior

Joined: Thu Aug 25, 2005 3:35 am
Posts: 160
I use only composite keys (can't change the schema).
Just create an interceptor and implement the isUnsaved and findDirty stuff yourself. Then it will save correctly.

Or use a version.. that way it will know whether to insert or update as well.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 21, 2006 4:44 pm 
Newbie

Joined: Thu Mar 16, 2006 10:07 pm
Posts: 3
Location: New Zealand
TheShark wrote:
I use only composite keys (can't change the schema).
Just create an interceptor and implement the isUnsaved and findDirty stuff yourself. Then it will save correctly.

Or use a version.. that way it will know whether to insert or update as well.


I'm kinda new to NHibernate, are you able to elaborate on isUnsaved, findDirty and version?

I'm assuming isUnsaved and version are overloaded methods on the data objects, are you able to tell me which interface to implement or class to extend?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 22, 2006 8:06 am 
Senior
Senior

Joined: Thu Aug 25, 2005 3:35 am
Posts: 160
There is more then enough documentation that will help you with these questions. ..........
But in short, you can implement an interface that will be called to do a findDirty. It's of type IInterceptor and you should pass it as a parameter when creating a sessionfactory.

hope that helps.


Top
 Profile  
 
 Post subject: composite-id and NH
PostPosted: Thu Nov 09, 2006 8:55 am 
Beginner
Beginner

Joined: Wed Aug 09, 2006 10:15 am
Posts: 20
Location: Vitoria - ES - Brazil
That is the 4th problema I found so far with NH and composite-id objects.

1 - GetHashCode must be implemented manually
2 - Equals must be implemented manually
3 - I can not use identity or any generator class
4 - NH do not detect and neither warns if it is a dirty or unsaved object
( so cascading lists do not work properly )

I wonder if NH 1.0.3 has solved these problems cited above.
If not maybe NH 2.1 Beta does ?

I know I can solve these problems with the interceptor class but I was expecting the ORM tool to do this work for me.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 13, 2007 7:58 pm 
Regular
Regular

Joined: Fri Feb 03, 2006 5:28 pm
Posts: 73
Location: Québec, QC, Canada
Has this been fixed with new versions?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

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.