When saving an entity, related entity causes exception

Posts   
 
    
KL
User
Posts: 11
Joined: 31-Aug-2006
# Posted on: 16-Jan-2007 17:33:59   

I'm using LLBLGen Pro 2.0.0.0 Final (December 6th, 2006) with MS SQL Server 2000 and .Net 1.1 -- using the Adapter method

I have an entity called Contact and a related entity ContactDestination in a 1:n relationship.

Contact maps to the Contacts table which has the following fields ContactID (PK, Identity) FirstName LastName Deleted

ContactDestination maps to the ContactDestinations table which has the following fields: ContactID (PK, FK to Contacts table) DestinationTypeID (PK) Destination Disabled

ContactDestination is also a super-type in an target-per-heirarchy inheritance where DestinationTypeID is the descriminator.

The problem is when I save a Contact (recursively) LLBLGen tries to save the related ContactDestination with a ContactID of 0 (which is invalid/does not exist, and thus I get an exception because of the foreign key constraint), and I'm not sure why. I have a feeling it has something to do with my inheritance and/or one of my relationships just aren't being set properly.

Here's a description of what I think may be the root of the problem: The Contact entity has a relationship with ContactDestination. Like I mentioned, I have subtypes of ContactDestinations; I added custom 1:n relationships between contacts and these subtypes. I also made ContactDestination abstract. I hid the relationship between the subtypes and Contacts on the subtypes' side because when the code was being generated, the relationship was conflicting with the pre-existing relationship between Contact and ContactDestination (i.e. would not build because there were properties that had the same name -- which was a result of ContactDestination AND its subtypes having a relationship with Contact). I hope I explained that clearly (doubt it wink ), but that's what I think I did wrong... if so, what's the "proper" way to do this?

Debug output

Method Exit: CreateSelectDQ Method Exit: CreatePagingSelectDQ: no paging. Method Enter: DataAccessAdapterBase.ExecuteMultiRowRetrievalQuery Method Enter: DataAccessAdapterBase.OpenConnection Method Exit: DataAccessAdapterBase.OpenConnection Method Exit: DataAccessAdapterBase.ExecuteMultiRowRetrievalQuery Method Exit: DataAccessAdapterBase.FetchEntityCollectionInternal(6) Method Enter: DataAccessAdapterBase.CloseConnection Method Exit: DataAccessAdapterBase.CloseConnection Method Exit: DataAccessAdapterBase.FetchEntityCollection(3) Method Enter: DataAccessAdapterBase.StartTransaction Method Enter: DataAccessAdapterBase.OpenConnection Method Exit: DataAccessAdapterBase.OpenConnection Method Exit: DataAccessAdapterBase.StartTransaction Method Enter: DataAccessAdapterBase.SaveEntity(4) Method Enter: DataAccessAdapterBase.DetermineActionQueues(7) Method Exit: DataAccessAdapterBase.DetermineActionQueues(7) Method Enter: DataAccessAdapterBase.PersistQueue Method Enter: CreateInsertDQ Method Enter: CreateSingleTargetInsertDQ Generated Sql query: Query: INSERT INTO [dbo].[Contacts] ([FirstName], [LastName]) VALUES (@FirstName, @LastName);SELECT @ContactId=SCOPE_IDENTITY() Parameter: @ContactId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Output. Value: <undefined value>. Parameter: @FirstName : AnsiString. Length: 50. Precision: 0. Scale: 0. Direction: Input. Value: "asdf". Parameter: @LastName : AnsiString. Length: 50. Precision: 0. Scale: 0. Direction: Input. Value: "fdsa".

Method Exit: CreateSingleTargetInsertDQ Method Exit: CreateInsertDQ Method Enter: DataAccessAdapterBase.ExecuteActionQuery Method Enter: DataAccessAdapterBase.OpenConnection Method Exit: DataAccessAdapterBase.OpenConnection Method Enter: Query.ReflectOutputValuesInRelatedFields Method Exit: Query.ReflectOutputValuesInRelatedFields Method Exit: DataAccessAdapterBase.ExecuteActionQuery Method Enter: DataAccessAdapterBase.FetchEntity(1) Method Enter: DataAccessAdapterBase.FetchEntityUsingFilter(3) Method Enter: CreatePagingSelectDQ Method Enter: CreateSelectDQ Method Enter: CreateSelectDQ Generated Sql query: Query: SELECT [dbo].[Contacts].[ContactID] AS [ContactId], [dbo].[Contacts].[FirstName], [dbo].[Contacts].[LastName], [dbo].[Contacts].[Deleted] FROM [dbo].[Contacts] WHERE ( ( [dbo].[Contacts].[ContactID] = @ContactId1)) Parameter: @ContactId1 : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 7.

Method Exit: CreateSelectDQ Method Exit: CreatePagingSelectDQ: no paging. Method Enter: DataAccessAdapterBase.ExecuteSingleRowRetrievalQuery Method Enter: DataAccessAdapterBase.OpenConnection Method Exit: DataAccessAdapterBase.OpenConnection Method Exit: DataAccessAdapterBase.ExecuteSingleRowRetrievalQuery Method Exit: DataAccessAdapterBase.FetchEntityUsingFilter Method Exit: DataAccessAdapterBase.FetchEntity(1) Method Enter: CreateInsertDQ Method Enter: CreateSingleTargetInsertDQ Generated Sql query: Query: INSERT INTO [dbo].[ContactDestinations] ([ContactID], [DestinationTypeID], [Destination], [Disabled]) VALUES (@ContactId, @DestinationTypeId, @Value, @Disabled) Parameter: @ContactId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 0. Parameter: @DestinationTypeId : Int32. Length: 0. Precision: 10. Scale: 0. Direction: Input. Value: 1001. Parameter: @Value : AnsiString. Length: 50. Precision: 0. Scale: 0. Direction: Input. Value: "321". Parameter: @Disabled : Boolean. Length: 0. Precision: 1. Scale: 0. Direction: Input. Value: False.

Method Exit: CreateSingleTargetInsertDQ Method Exit: CreateInsertDQ Method Enter: DataAccessAdapterBase.ExecuteActionQuery Method Enter: DataAccessAdapterBase.OpenConnection Method Exit: DataAccessAdapterBase.OpenConnection Method Exit: DataAccessAdapterBase.ExecuteActionQuery Method Exit: DataAccessAdapterBase.SaveEntity(4) Method Enter: DataAccessAdapterBase.Rollback Method Enter: DataAccessAdapterBase.CloseConnection Method Exit: DataAccessAdapterBase.CloseConnection Method Exit: DataAccessAdapterBase.Rollback

Exception:

An exception was caught during the execution of an action query: INSERT statement conflicted with COLUMN FOREIGN KEY constraint 'FK_ContactDestinations_Contacts'. The conflict occurred in database 'SpeechEzyV3_DEV', table 'Contacts', column 'ContactID'. The statement has been terminated.. Check InnerException, QueryExecuted and Parameters of this exception to examine the cause of this exception.

SD.LLBLGen.Pro.ORMSupportClasses.ActionQuery.Execute() in C:\Documents and Settings\KL\My Documents\My Visual Studio Projects\Notification Data Access Layer\ORMSupportClasses\ActionQuery.cs:line 193 at SD.LLBLGen.Pro.ORMSupportClasses.BatchActionQuery.Execute() in C:\Documents and Settings\KL\My Documents\My Visual Studio Projects\Notification Data Access Layer\ORMSupportClasses\BatchActionQuery.cs:line 112 at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.ExecuteActionQuery(IActionQuery queryToExecute) in c:\documents and settings\kl\my documents\my visual studio projects\notification data access layer\ormsupportclasses\dataaccessadapterbase.cs:line 515 at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.PersistQueue(ArrayList queueToPersist, Boolean insertActions) in c:\documents and settings\kl\my documents\my visual studio projects\notification data access layer\ormsupportclasses\dataaccessadapterbase.cs:line 1488 at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.SaveEntity(IEntity2 entityToSave, Boolean refetchAfterSave, IPredicateExpression updateRestriction, Boolean recurse) in c:\documents and settings\kl\my documents\my visual studio projects\notification data access layer\ormsupportclasses\dataaccessadapterbase.cs:line 1346 at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.SaveEntity(IEntity2 entityToSave, Boolean refetchAfterSave) in c:\documents and settings\kl\my documents\my visual studio projects\notification data access layer\ormsupportclasses\dataaccessadapterbase.cs:line 1200 at EscalationNotification.BusinessLayer.Controller.SaveContact(ContactEntity& ModifiedContact, Int32[] ContactGroupIDs) in C:\Documents and Settings\KL\My Documents\My Visual Studio Projects\Notification Business Layer\EscalationNotification.BusinessLayer\Controller.vb:line 131

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 17-Jan-2007 00:24:43   

You have to rename hte field mapped onto the relation in the subtypes, so you don't have the clashes (though I doubt you'll get this a lot as the relation is in the root of the hierarchy). You can't hide the relation from the FK side (subtypes) if you want to have the FK field being synced with the PK field as the FK side starts the synchronization and if the relation from the FK to the PK side is hidden, the fk side (contactdescription) doesn't know about contact so no syncing is taken place.

Frans Bouma | Lead developer LLBLGen Pro