Strange behavior with 1:1 relation

Posts   
 
    
Didier avatar
Didier
User
Posts: 7
Joined: 13-Jul-2006
# Posted on: 02-Aug-2006 12:15:23   

Hi,

I am using LLBLGen Pro v2 with an Access 2000 database. The generator template used is the SelefServicing.TwoClasses for VB.NET 2.0.

I have a strange behavior with generated code for a 1:1 relation as showed below:


        Dim dossier As New DossierEntity()
        dossier.TypeDossier = "MIT-456"
        dossier.Save(True)

        Dim infos1 As DetailInformationEntity = dossier.DetailInformation
        Dim infos2 As DetailInformationEntity = dossier.DetailInformation 'infos1 <> infos2 !!!


        infos1.AltitudeSaisie = 345
        infos1.Save(True)

        infos2.AltitudeSaisie = 222
        infos2.Save(True) 'exception occur: "The changes you requested to the table were not successful 
                                   'because they would create duplicate values in the index, primary key, 
                                   'or 'relationship....."

In fact, the property DetailInformation is calling the GetSingleDetailInformation method but this one returns always a new object DetailInformationEntity. This is the reason of the exception during the infos2's save (try to insert twice a row with the same PK).

Is this a bug or a problem of use ?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 02-Aug-2006 15:57:47   

Try it without the True boolean parameter in the save methods, as follows:

infos1.AltitudeSaisie = 345
        infos1.Save()

        infos2.AltitudeSaisie = 222
        infos2.Save() 'exception occur: "The changes you requested to the table were not successful 

Also make sure that infos1 & infos2 don't have the same PK before the save operation.

Didier avatar
Didier
User
Posts: 7
Joined: 13-Jul-2006
# Posted on: 03-Aug-2006 14:09:51   

Walaa wrote:

Try it without the True boolean parameter in the save methods, as follows:

infos1.AltitudeSaisie = 345
        infos1.Save()

        infos2.AltitudeSaisie = 222
        infos2.Save() 'exception occur: "The changes you requested to the table were not successful 

I try it with wame result : exception occur on the second save.

Also make sure that infos1 & infos2 don't have the same PK before the save operation.

Below the specs of my database:

Table Dossier: + idDossier (PK) + id_idDossier(FK) reference the DetailInformation PK + some data fields

Table DetailInformation: + idDossier (PK) (FK) reference the Dossier PK + some data fields

This is my 1:1 relation between 'Dossier' and 'DetailInformation'. With this specification the infos1 and infos2 must have the same PK, currently this is ok, and must be the same object in memory, currently this is don't work : could you explain why ?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 03-Aug-2006 16:13:13   

Dim infos1 As DetailInformationEntity = dossier.DetailInformation Dim infos2 As DetailInformationEntity = dossier.DetailInformation 'infos1 <> infos2 !!!

If you wanted infos1 and infos2 to have the same memory reference then you should have created them using a singlton factory.

And since you are returning new instances each appears to have IsNew = true Which signals a database INSERT when it gets saved.

And due to PK-FK Sync both would have the same unique FK value (which by the way is the PK).

This can't be inserted twice.

Didier avatar
Didier
User
Posts: 7
Joined: 13-Jul-2006
# Posted on: 03-Aug-2006 16:56:41   

Walaa,

thanks for your answer.

Walaa wrote:

And since you are returning new instances each appears to have IsNew = true Which signals a database INSERT when it gets saved.

And due to PK-FK Sync both would have the same unique FK value (which by the way is the PK).

This can't be inserted twice.

Yes, it's exactly the problem.

Walaa wrote:

If you wanted infos1 and infos2 to have the same memory reference then you should have created them using a singlton factory.

DetailInformation property of DossierEntity is generated by LLBLGEN and call GetSingleDetailInformation(). Why this method don't use the singleton pattern to create the new DetailInformationEntity according to the 1:1 relation?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 04-Aug-2006 08:11:40   

Since it's normal to only use it to retrieve one object.

I don't understand why you use this code:

    infos1.AltitudeSaisie = 345
        infos1.Save(True)

        infos2.AltitudeSaisie = 222
        infos2.Save(True) 

Why don't you only use one instance of infos? If you want one instance then simply the following code would work:

Dim dossier As New DossierEntity()
        dossier.TypeDossier = "MIT-456"
        dossier.Save(True)

        Dim infos1 As DetailInformationEntity = dossier.DetailInformation

        infos1.AltitudeSaisie = 345
        infos1.Save(True)

        infos1.AltitudeSaisie = 222
        infos1.Save(True)
Didier avatar
Didier
User
Posts: 7
Joined: 13-Jul-2006
# Posted on: 10-Aug-2006 13:31:04   

Sorry for the delay.

Walaa wrote:

Since it's normal to only use it to retrieve one object.

I don't understand why you use this code:

    infos1.AltitudeSaisie = 345
        infos1.Save(True)

        infos2.AltitudeSaisie = 222
        infos2.Save(True) 

Why don't you only use one instance of infos?

I posted the previous sample example in order to show the unexpected behavior of the GetSingleXXX method.

If you want one instance then simply the following code would work:

Dim dossier As New DossierEntity()
        dossier.TypeDossier = "MIT-456"
        dossier.Save(True)

        Dim infos1 As DetailInformationEntity = dossier.DetailInformation

        infos1.AltitudeSaisie = 345
        infos1.Save(True)

        infos1.AltitudeSaisie = 222
        infos1.Save(True)

Agree.

But, for example, I have a form with, in the first half, a grid contains a list of DossierEntity and, in the second half some textbox and other databinded components on the DetailInformationEntity of the grid's selected DossierEntity. The wanted behavior is : save the collection only when I quit this form (not when I change the selected "Dossier").

Well! Please read this small scenario: 1) select a DossierEntity named 'Dossier1'. I never enter any information previously for this DossierEntity's DetailInformationEntity (no row in database). 2) put some information in DetailInformationEntity. 3) select an other DossierEntity in the grid 4) select the 'Dossier1' (same as in step 1). You have lost the DetailInformationEntity. There is a new Entity instead.

Of course I can save recursively the Selected DossierEntity on selection change or else when I create a DossierEntity I can create a DetailInformationEntity and save it. But I don't want to change the save information behavior and I can't either in each portion of code which concern entity creation add a hack for solve this strange behavior.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 10-Aug-2006 13:55:37   

You should not reload the related entity each time you access it. Please refer to the LLBLGen Pro manual "Using the generated code -> Adapter/ SelfServicing -> Using the entity classes" read the paragraph titled Load on demand/Lazy loading