Bug? Entity dirty after fetch via prefetch when using DEFAULT Constraint and FOREIGN KEY on same field

Posts   
 
    
acl
User
Posts: 99
Joined: 28-Mar-2012
# Posted on: 06-Jun-2025 11:58:14   

Hi,

I am using version 5.11.2 of the LLBLGen Runtime Framework and the LLBLGen Designer.

After 10 Years of using LLBLGen, I might have found one bug.

The problem is that after fetching an entity from the database, it is immediately marked dirty. Even though it was just fetched, and we did not change anything.

After lots of searching, I managed to reduce it to the following minimal sample. The requirements needed to produce this bug:

  • An entity with a field that has both a DEFAULT constraint AND a FOREIGN KEY constraint.

  • When this entity is part of a prefetch, then the prefetched entity is dirty


-- This is not real SQL but should be sufficient to understand the situation

CREATE TABLE TMonth (
  TMonth_Id tinyint NOT NULL PRIMARY KEY
  TMonth_Name varchar(100) NULL
)

CREATE TABLE TSample (
  TSample_Id int NOT NULL PRIMARY KEY,
  TFirm_StartMonat tinyint NOT NULL FOREIGN KEY TO TMonth AND DEFAULT CONSTRAINT with value 1
  TSample_IdOtherSample int NULL FOREIGN KEY TO TSample
)

Now when I fetch a TSample Entity with a Prefetch of TSample_IdOtherSample, then the prefetched entity (TSample_IdOtherSampleEntity) is always dirty. This is due to the TMonth_Id field, which has IsChanged set to true. This is due to it having a default constraint in the database

I looked through Google and various AI assistants and it appears, that LLBLGen needs to know the value of the default constraint in the model, to be able to do dirty checking. However, we cannot define this value since the field also has a foreign key constraint.

edit wrong ChatGPT statement removed.

Thanks,

andreas

Attachments
Filename File size Added on Approval
Entity Fields.png 9,866 12-Jun-2025 15:43.10 Approved
Catalog Details Viewer.png 9,533 12-Jun-2025 15:43.24 Approved
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39887
Joined: 17-Aug-2003
# Posted on: 07-Jun-2025 07:32:17   

We'll look into it

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39887
Joined: 17-Aug-2003
# Posted on: 09-Jun-2025 09:20:30   

ChatGPT is wrong, default values on table fields are read just fine and not stripped off. Please next time, don't post any AI slop text, and just the code you use to reproduce the issue, that will save us all some time.

Because an essential detail is missing: did you also prefetch the Month entity? So I'd like to know the exact prefetch path that produces the issue together with the exact table structure and the data in the rows to reproduce the issue. Data here is important as it's a prefetch path related issue. So please post these so we can use that to investigate the issue, otherwise we have to trial/error and guess what exactly is the situation in your case.

Frans Bouma | Lead developer LLBLGen Pro
acl
User
Posts: 99
Joined: 28-Mar-2012
# Posted on: 12-Jun-2025 15:47:00   

Hi Otis,

sorry, indeed ChatGPT was wrong. I removed the bad statement to avoid it being found by some other AI or human..

To answer your question about prefetching the Month entity: no, I don't do that. I did add it to the prefetch path just as a test, but this did not change anything.

I did as requested and tried creating a repro project with only the entities and tables required to reproduce the bug. As often, I was not able to reproduce the issue at first.

Finally, I noticed that the following piece of code is required to produce the behavior:

Private Sub InitClassEmpty(validator As IValidator, fields As IEntityFields2)
                OnInitializing()
                If fields Is Nothing Then
                               Me.Fields = CreateFields()
                Else
                               Me.Fields = fields
                End If
                Me.Validator = validator
                InitClassMembers()

                ' __LLBLGENPRO_USER_CODE_REGION_START InitClassEmpty
                Me.TFirm_StartMonat = 1
                ' __LLBLGENPRO_USER_CODE_REGION_END

                OnInitialized()
End Sub

The line Me.TFirm_StartMonat = 1 was added to enable us to save an empty entity without having to explicitly set the value of TFirm_StartMonat.

This is to emulate the default constraint on the column. Maybe there is another way to achieve this. I attached two screenhots above. One shows that the field does have a default constraint. The other shows the entity field, where there is no mention of a default value.

Maybe this is sufficient for you, otherwise, I will have to create the sample project as requested.

Thanks,

andreas

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39887
Joined: 17-Aug-2003
# Posted on: 12-Jun-2025 17:13:29   

Isn't that piece of code, Me.TFirm_StartMonat = 1 precisely the reason it happens? A new entity instance is created, it's setting that value and that triggers the dirty flag as you go through the field set code. If you want to set the value without triggering dirty checking, then you should force write the value directly, using Me.Fields.ForcedValueWrite(CInt(TSampleEntityFields.TFirm_StartMonat), 1)

Initializing fields the way you do will set the field as changed...

Frans Bouma | Lead developer LLBLGen Pro