TestCurrentValueForNull returns wrong value.

Posts   
 
    
alejado
User
Posts: 2
Joined: 18-May-2008
# Posted on: 18-May-2008 01:51:15   

The steps to reproduce the problem are:

  • I have a freshly-fetched TestEntity with field FieldA set to a non-null value.

  • I set the field to null using a SetNewFieldValue((int)TestFieldIndex.FieldA, null); (Setting it via the property does not affect the problem). ---> The TestEntity.TestCurrentValueForNull(TestFieldIndex.FieldA) call returns true, as it should.

  • I save the TestEntity with TestEntity.Save(false); ---> The TestEntity.TestCurrentValueForNull(TestFieldIndex.FieldA) call returns false (wrong value) until a field is accessed using a property, i.e. until getting the value of TestEntity.FieldA.

I am using LLBLGen Pro 2.5 with SQL Server 2005 on Windows XP.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 19-May-2008 07:00:14   

Hi alejado.

I reproduced the issue. We will look into it ASAP.

David Elizondo | LLBLGen Support Team
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 19-May-2008 13:44:49   

It's a bit tricky. Because the entity is actually 'out of sync' it's not really possible to say if the routine should return true or false: only after the entity has been refetched.

It checks if the entity is new or not. As the entity has been saved, it isn't new. So it checks whether the field has been changed. It's not marked as changed after a save, so it checks if the IsNull flag is true. But as the entity has never been loaded, that flag is false, so it reports false.

To get rid if this, the selfservicing entity first should check for refetch, and if so, refetch the entity. That will get rid of the error, but in the context of the call, the answer returned, is that the answer you're looking for? -> the answer returned after a refetch is the fact if the field in the DB is null or not (as it refetches the entity), not what it had at the moment you called the routine.

So adding the check for refetch... is that really helping? It might sound silly, but take into account an entity where you set a field to null, and it has a default constraint for that field. You save the entity. In the database, the field gets a default value, not null. When you call the method to test the current value for null, you'll get false, while the value in memory at that moment is null! (so you expected true).

Frans Bouma | Lead developer LLBLGen Pro
obzekt
User
Posts: 60
Joined: 29-Apr-2004
# Posted on: 19-May-2008 15:24:11   

I don't know if it's the name of the API, but this seems like a bug to me. It's very misleading. If you call Save, then TextCurrentValueForNull should return the proper value, you shouldn't have to refetch. Is it possible to have that fixed soon (our beta is out any day now), or do you consider it as designed? We need to know and plan ahead. Thanks.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 19-May-2008 16:22:38   

obzekt wrote:

I don't know if it's the name of the API, but this seems like a bug to me. It's very misleading. If you call Save, then TextCurrentValueForNull should return the proper value, you shouldn't have to refetch. Is it possible to have that fixed soon (our beta is out any day now), or do you consider it as designed? We need to know and plan ahead. Thanks.

It will always refetch, as the entity in-memory is out of sync. So if you want to avoid the refetch, you're not going to be able to do that.

I can add the check to the routine, it will just give false positives in other situations as I described above. I know this is a semantic issue, how one look at things, but it's important that it's defined how to look at things.

If you want to test on the in-memory object after the save, before the refetch, i.e. the entity which is out of sync, I wonder why you want to do that. Aren't you interested in the value for the field in the entity instance (data) ?

Frans Bouma | Lead developer LLBLGen Pro
alejado
User
Posts: 2
Joined: 18-May-2008
# Posted on: 19-May-2008 20:30:26   

Otis wrote:

It's a bit tricky. Because the entity is actually 'out of sync' it's not really possible to say if the routine should return true or false: only after the entity has been refetched.

It checks if the entity is new or not. As the entity has been saved, it isn't new. So it checks whether the field has been changed. It's not marked as changed after a save, so it checks if the IsNull flag is true. But as the entity has never been loaded, that flag is false, so it reports false. ...

Actually, it does not always return "false", it returns the value that it would return before FieldA changed. For example, if FieldA was non-null before the change and the save, then the CheckNewFieldValueForNull call returns "true" after the save, even if FieldA was set to a non-null value before the save. Also, getting a field value after the save (whatever field, not just FieldA) from that entity seems to fix the problem and the call returns the correct value (because it does the refetch).

// Edit

A good solution for now is to place an override of EntityBase.CheckIfCurrentFieldValueIsNull in CommonEntityBase so that a call to CheckForPrefetch() is made before doing the null check. However, since the correct behavior is not to be able to look at out-of-sync data, the CheckForPrefetch() call should be added to the EntityBase implementation, to behave like GetValue() does.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 21-May-2008 10:57:30   

alejado wrote:

Otis wrote:

It's a bit tricky. Because the entity is actually 'out of sync' it's not really possible to say if the routine should return true or false: only after the entity has been refetched.

It checks if the entity is new or not. As the entity has been saved, it isn't new. So it checks whether the field has been changed. It's not marked as changed after a save, so it checks if the IsNull flag is true. But as the entity has never been loaded, that flag is false, so it reports false. ...

Actually, it does not always return "false", it returns the value that it would return before FieldA changed. For example, if FieldA was non-null before the change and the save, then the CheckNewFieldValueForNull call returns "true" after the save, even if FieldA was set to a non-null value before the save. Also, getting a field value after the save (whatever field, not just FieldA) from that entity seems to fix the problem and the call returns the correct value (because it does the refetch).

// Edit

A good solution for now is to place an override of EntityBase.CheckIfCurrentFieldValueIsNull in CommonEntityBase so that a call to CheckForPrefetch() is made before doing the null check. However, since the correct behavior is not to be able to look at out-of-sync data, the CheckForPrefetch() call should be added to the EntityBase implementation, to behave like GetValue() does.

Yes, that's also what I was thinking, the downside is that it might give results one wouldn't expect in other situations...

I do agree that the necessity of calling the fetch manually is a 'workaround' which shouldn't have to be necessary. I'll add the call to v2.6's Runtimelib.

Frans Bouma | Lead developer LLBLGen Pro