Automatic insertion of foreign keys doesn't seem to be working

Posts   
 
    
Posts: 13
Joined: 15-Jan-2006
# Posted on: 11-Oct-2006 04:58:44   

Hello,

I have the following object hierarchy (renamed for simplicity):

1) Person table - PersonID PK identity - FirstName - LastName

2) Employee table - PersonID PK FK 1:1 references Person.PersonID - EmployeeNumber

3) Paycheck table - PaycheckID PK identity - PersonID FK m:1 references Employee.PersonID - Amount

I am using a Target-Per-Entity inheritance relationship between Employee and Person.

My Scenario: 1) Create an instance of Employee. 2) Set the FirstName, LastName, and EmployeeNumber fields 3) Create 2 new instances of Paycheck and set the Amount property only. 4) Add the Paycheck instances to the Employee's Paycheck collection. 5) Call DataAccessAdapter.Save(employee, true, true) (refetch and recurse)

When this happens, I receive a database error stating that the Paycheck.PersonID column cannot contain null values. When I look at the insert query, the PersonID field is not even present.

I know LLBL supports automatic updates of foreign keys when doing recursive saves. Is the problem that I'm using an object hierarchy?

LLBL Version: LLBL 2.0.0.0 Final (July 12th, 2006) Runtime Version: 2.0.0.060722 Template: .NET 2.0 Adapter Database: SQL Server 2005

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 11-Oct-2006 08:43:05   

Please use the latest release of v.2, you are using an old release of the runtime Library.

If the problem still exists, please post real code snippet.

Posts: 13
Joined: 15-Jan-2006
# Posted on: 11-Oct-2006 17:05:23   

Hi Walaa,

Thanks for responding to my posting. I updated to the latest version of the Designer and Runtime Libraries, but I'm still having the problem. Here is my code:

HughesCallEntity call = new HughesCallEntity();

call.ProgramCode = "12345";
call.Pin = "1234";
call.PackageId = 1;
call.CustomerId = 2684;
call.OrderProviderId = "HU";
call.LeadRepCallStart = DateTime.Now.ToUniversalTime();
call.LeadRepUserId = 1;
call.SalesRepUserId = 1;
call.StatusId = (int)CallStatus.OnCall;
call.SalesLocationId = 1;
call.Uuid = Guid.NewGuid();

HughesCallOptionEntity option = new HughesCallOptionEntity();
option.HughesOptionId = 1;
option.Sku = "ABCD";
option.OneTimeCost = 1M;

call.CallOptions.Add(option);

using (DataAccessAdapter adapter = new DataAccessAdapter(connectionString))
{
    adapter.SaveEntity(call, true, true);
}

I have uploaded several screenshots of my LLBL designer as well as my lgp project file to http://www.thebhwgroup.com/llbl

Thanks for any help you can provide!

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 11-Oct-2006 17:21:45   

In the DB, is the HughesCallOptionEntity related to the HughesCallEntity or to its parent (OrderProviderCall)?

Posts: 13
Joined: 15-Jan-2006
# Posted on: 11-Oct-2006 17:24:11   

HughesCallOptionEntity is related to HughesCallEntity.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 11-Oct-2006 18:13:37   

It's better you remove the .lgp and exception from the url you specified.

With the description you gave in the first post it should be possible to reproduce it. I'll try to reproduce it, however I don't really understand why it doesn't work. It seems the FK isn't synced correctly when the PK is updated after the insert of the full hierarchy. This is odd, as the sync information should simply pull the value from the PK entity.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 13
Joined: 15-Jan-2006
# Posted on: 11-Oct-2006 19:13:29   

Ok, I removed those files. Let me know if you have any trouble reproducing the error.

Thanks!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 12-Oct-2006 11:01:46   

I can't reproduce it.

My testcode:


[Test]
public void PkFkSyncFromSubTypeTest()
{
    Employee2Entity toInsert = new Employee2Entity();
    toInsert.FirstName = "Frans";
    toInsert.LastName = "Bouma";
    toInsert.EmployeeNumber = 123;
    PaycheckEntity pc1 = new PaycheckEntity();
    pc1.Amount = 10.0M;
    PaycheckEntity pc2 = new PaycheckEntity();
    pc2.Amount = 10000.0M;
    toInsert.Paycheck.Add(pc1);
    toInsert.Paycheck.Add(pc2);

    using(DataAccessAdapter adapter = new DataAccessAdapter())
    {
        Assert.IsTrue(adapter.SaveEntity(toInsert, true, true));
    }

    Assert.IsTrue((toInsert.PersonId > 0));
    Assert.AreEqual(toInsert.PersonId, pc1.PersonId);
    Assert.AreEqual(toInsert.PersonId, pc2.PersonId);
}

My tables:


CREATE TABLE [dbo].[Employee2] (
    [PersonID] [int] NOT NULL ,
    [EmployeeNumber] [int] NOT NULL 
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Paycheck] (
    [PaycheckID] [int] IDENTITY (1, 1) NOT NULL ,
    [PersonID] [int] NOT NULL ,
    [Amount] [money] NOT NULL 
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Person] (
    [PersonID] [int] IDENTITY (1, 1) NOT NULL ,
    [FirstName] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
    [LastName] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL 
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Employee2] WITH NOCHECK ADD 
    CONSTRAINT [PK_Employee2] PRIMARY KEY  CLUSTERED 
    (
        [PersonID]
    )  ON [PRIMARY] 
GO

ALTER TABLE [dbo].[Paycheck] WITH NOCHECK ADD 
    CONSTRAINT [PK_Paycheck] PRIMARY KEY  CLUSTERED 
    (
        [PaycheckID]
    )  ON [PRIMARY] 
GO

ALTER TABLE [dbo].[Person] WITH NOCHECK ADD 
    CONSTRAINT [PK_Person] PRIMARY KEY  CLUSTERED 
    (
        [PersonID]
    )  ON [PRIMARY] 
GO

ALTER TABLE [dbo].[Employee2] ADD 
    CONSTRAINT [FK_Employee2_Person] FOREIGN KEY 
    (
        [PersonID]
    ) REFERENCES [dbo].[Person] (
        [PersonID]
    )
GO

ALTER TABLE [dbo].[Paycheck] ADD 
    CONSTRAINT [FK_Paycheck_Employee2] FOREIGN KEY 
    (
        [PersonID]
    ) REFERENCES [dbo].[Employee2] (
        [PersonID]
    )
GO

(I used Employee2 as my inheritance unit test db already had an Employee table wink )

I'm not sure what caused this at your side though. Could you please test this in your project with the tables and code I used as well and check whether I made a proper unittest or that it doesn't mimic your usage scenario.

Frans Bouma | Lead developer LLBLGen Pro
Posts: 13
Joined: 15-Jan-2006
# Posted on: 12-Oct-2006 17:19:50   

Ah ha! I think I figured out the issue. Using this example, go into the LLBL designer, expand Paycheck and hide the Employee2 field mapped on the Paycheck - Employee2 relation. Once you do that, you should get the error.

Now, that I know I can just unhide the field, this issue is not so critical any more. Thanks for helping me look into it!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 12-Oct-2006 17:32:00   

Ok, that's indeed logical: paycheck then doesn't know about Employee2 and won't subscribe to its events nor won't it setup syncing with Employee2. simple_smile

Why did you hide that field btw?

Frans Bouma | Lead developer LLBLGen Pro
Posts: 13
Joined: 15-Jan-2006
# Posted on: 12-Oct-2006 17:36:59   

I usually hide all of the fields that I don't plan on using. Now that I know this could cause problems, I'll probably stop doing that simple_smile