Cannot set a field to null.

Posts   
 
    
astrouk
User
Posts: 53
Joined: 13-Jun-2006
# Posted on: 25-May-2007 02:18:22   

Hello,

The error I am reporting is quite simple. A field cannot be set to null regardless if it is nullable or not.

Code below


CustomerEntity entity = new CustomerEntity(23043);
entity.EmployerId = null;
entity.Notes = "Updated:" + System.DateTime.Now;
entity.Save();

Or


CustomerEntity entity = new CustomerEntity(23043);
entity.SetNewFieldValue((int)CustomerFieldIndex.EmployerId, null);
entity.Notes = "Updated:" + System.DateTime.Now;
entity.Save();

results in the following query:

Query: UPDATE "GEN_ODS"."PER_CUSTOMER" SET "NOTES"=:Notes1 WHERE ( "GEN_ODS"."PER_CUSTOMER"."ID" = :Id2) Parameter: :Notes1 : String. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: "Updated:5/24/2007 4:57:39 PM". Parameter: :Id2 : Decimal. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 23043.

As you can see EmployerId is missing.

DB: Oracle 10g LLBLGen: 2.0, Latest version Template: SelfServicing EmployerID type: Number EmployerID original value: 60135

Same is true for other fields.

Unfortunately, I can't come up with acceptable workaround. All I can do at this point is to set a field to null by updating it to 0 and catching it in a trigger. I don't like this approach, of course.

Alex

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 25-May-2007 09:44:42   

Which LLBLGen Pro runtime library build are you using?

astrouk
User
Posts: 53
Joined: 13-Jun-2006
# Posted on: 25-May-2007 19:47:35   

Walaa wrote:

Which LLBLGen Pro runtime library build are you using?

Mar 21st, I guess. I'll update them today. However I can't see this error in a changelog anyway.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 25-May-2007 21:08:19   

Could you check if the EmployerId field is already null ? Because if it is, it's not set again.

If it has a value, could you please check if the customer.Fields["EmployerId"].IsChanged flag is set after you set the field to null ?

Frans Bouma | Lead developer LLBLGen Pro
astrouk
User
Posts: 53
Joined: 13-Jun-2006
# Posted on: 26-May-2007 01:16:59   

Hi, Frans

Otis wrote:

Could you check if the EmployerId field is already null ? Because if it is, it's not set again.

No, it is not. As I said in a previous message it is 60135.

Otis wrote:

If it has a value, could you please check if the customer.Fields["EmployerId"].IsChanged flag is set after you set the field to null ?


CustomerEntity entity = new CustomerEntity(23043);
decimal employerId = entity.EmployerId;
//returns 60135
entity.SetNewFieldValue((int)CustomerFieldIndex.EmployerId, null);
bool flag = entity.Fields["EmployerId"].IsChanged;
//returns false
entity.Description = "Updated:" + System.DateTime.Now;
entity.Save();

Posts: 254
Joined: 16-Nov-2006
# Posted on: 26-May-2007 21:28:26   

1) Has the value can the read only attribute set, this can be set in the designer? Although this would normally throw an ORMFieldIsReadonlyException at runtime if this was the case.

2) Is the source column actually NULLABLE?

3) Is there any custom validation being performed on this field?

4) Do you override PreProcessValueToSet in this entity and do anything with this field?

astrouk
User
Posts: 53
Joined: 13-Jun-2006
# Posted on: 29-May-2007 23:41:49   

MattAdamson wrote:

1) Has the value can the read only attribute set, this can be set in the designer? Although this would normally throw an ORMFieldIsReadonlyException at runtime if this was the case.

2) Is the source column actually NULLABLE?

3) Is there any custom validation being performed on this field?

4) Do you override PreProcessValueToSet in this entity and do anything with this field?

  1. It is NOT read only.
  2. I did this test for both nullable and non-nullable fields. Result is the same.
  3. No
  4. No
Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 30-May-2007 10:28:06   

Strange !! Just bare with us.

2) Is the source column actually NULLABLE? 2. I did this test for both nullable and non-nullable fields. Result is the same.

Sorry but I have to double check on this, in case you were speaking about the database nullable status of the field, or the value in the Designer which may be different than the one generated in code in case you haven't re-generated the code after updating it in the Designer.

Would you please check and post the value of CustomerFields.EmployerId.SourceColumnIsNullable?

astrouk
User
Posts: 53
Joined: 13-Jun-2006
# Posted on: 31-May-2007 00:39:46   

Walaa wrote:

Strange !! Sorry but I have to double check on this, in case you were speaking about the database nullable status of the field, or the value in the Designer which may be different than the one generated in code in case you haven't re-generated the code after updating it in the Designer.

Would you please check and post the value of CustomerFields.EmployerId.SourceColumnIsNullable?

Sure. It is false.

Probably I must tell you that Customer entity is built on a view, not on a table. It is described here:

http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=9355&HighLight=1

So we use triggers to update the corresponding table(s). However in this case, as you can see from the first post, the correct update statement is never built.

Thank you.

Alex

P.S. I am going to check out now if I can set table fields to null.

astrouk
User
Posts: 53
Joined: 13-Jun-2006
# Posted on: 31-May-2007 00:57:53   

astrouk wrote:

P.S. I am going to check out now if I can set table fields to null.

Yeah, my suggestion was right. It works for table based entities and does not for view based entities.

This code


PersonEntity pentity = new PersonEntity(23043);
pentity.SetNewFieldValue((int)PersonFieldIndex.UpdatedByIdPer, null);
pentity.Description = "Updated:" + System.DateTime.Now;
pentity.Save();

results in:

Query: UPDATE "GEN_ODS"."PER_PERSON" SET "UPDATED_BY_ID"=:UpdatedByIdPer1,"DESCRIPTION"=Description2 WHERE ( "GEN_ODS"."PER_PERSON"."ID" = :Id3) Parameter: :UpdatedByIdPer1 : Decimal. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: <undefined value>. Parameter: Description2 : String. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: "Updated:5/30/2007 3:37:46 PM". Parameter: :Id3 : Decimal. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 23043.

while this


CustomerEntity entity = new CustomerEntity(23043);
bool isNullable = CustomerFields.EmployerId.SourceColumnIsNullable;
//returns false
decimal employerId = entity.EmployerId;
//returns 60135
entity.SetNewFieldValue((int)CustomerFieldIndex.EmployerId, null);
entity.Company = "Updated:" + System.DateTime.Now;
entity.Save();

corresponds to:

Query: UPDATE "GEN_ODS"."PER_CUSTOMER" SET "COMPANY"=:Company1 WHERE ( "GEN_ODS"."PER_CUSTOMER"."ID" = :Id2) Parameter: :Company1 : String. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: "Updated:5/30/2007 3:41:04 PM". Parameter: :Id2 : Decimal. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 23043.

CustomerEntity is based on a view, while PersonEntity is a table based one.

Well, I think it is a bugsimple_smile LLBLGen allows to update view based entities per se, but it doesn't allow to set entity fields to nulls. It doesn't throw any exception either. Besides, as I understand, LLBLGen should retrieve nullable flag from system table user_tab_columns.

select column_name, data_type, nullable from user_tab_columns where table_name = 'PER_CUSTOMER' returns EMPLOYER_ID, NUMBER, Y

Alex

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 31-May-2007 09:49:46   

Walaa wrote: Strange !! Sorry but I have to double check on this, in case you were speaking about the database nullable status of the field, or the value in the Designer which may be different than the one generated in code in case you haven't re-generated the code after updating it in the Designer.

Would you please check and post the value of CustomerFields.EmployerId.SourceColumnIsNullable?

Sure. It is false.

Probably I must tell you that Customer entity is built on a view, not on a table

SourceColumnIsNullable should be true, to enable setting the field to null.

As you have the entity mapped on to a view, the database view's metadata misses the information whether this field is nullable or not in the underlying table.

So what you can do is open the entity's properties in the Designer, select the specified field and check the "Is nullable" checkbox (also make sure "(.NET 2.0) Generate as nullable type" is checked), and re-generate the code.

astrouk
User
Posts: 53
Joined: 13-Jun-2006
# Posted on: 01-Jun-2007 03:40:27   

Walaa wrote:

SourceColumnIsNullable should be true, to enable setting the field to null.

As you have the entity mapped on to a view, the database view's metadata misses the information whether this field is nullable or not in the underlying table.

So what you can do is open the entity's properties in the Designer, select the specified field and check the "Is nullable" checkbox (also make sure "(.NET 2.0) Generate as nullable type" is checked), and re-generate the code.

Customer.EmployerID IS nullable in the Designer. I mentioned this fact in a second line of my first post. First one was "Hello" simple_smile

The error I am reporting is quite simple. A field cannot be set to null regardless if it is nullable or not.

Actually I have meant Designer here. I suspect that in case of DB non-nullable field I would get an exception and this discussion would never happen. I haven't tried it thoughsimple_smile

SourceColumnIsNullable for Customer.EmployerId returns false despite its .NET 2.0 "nullability". It returns true for a nullable field Person.UpdatedByIdPer which belongs to DB based entity.

Alex

astrouk
User
Posts: 53
Joined: 13-Jun-2006
# Posted on: 01-Jun-2007 04:22:04   

Here is the corresponding code from CustomerEntity.cs


public virtual Nullable<System.Decimal> EmployerId
{
      get
    {
       object valueToReturn = base.GetCurrentFieldValue((int)CustomerFieldIndex.EmployerId);
       return (Nullable<System.Decimal>)valueToReturn;
    }
      set{ SetNewFieldValue((int)CustomerFieldIndex.EmployerId, value); }
}

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 01-Jun-2007 11:47:04   

I can reproduce it with Oracle templates/selfservicing: a view's valuetype column is marked as nullable in the designer, the property is indeed Nullable<int> and the persistence info has 'false' for nullability of the TARGET column (the view column). It has true for nullability of the field as an entity field, however selfservicing checks if a field can be set to null using the sourcecolumnnullable flag which is false.

Because view fields are never set to be nullable (as that info isn't retrievable from db's as they don't store this meta-data often), the check in the runtime lib goes wrong for entity fields mapped onto a view field which has to be nullable in selfservicing (adapter doesn'thave this issue).

It should check the field info's isnullable flag, then it would succeed. I'll fix this in the runtime lib. If you can't wait for the fix, please manually set the field's sourcecolumnisnullable flag in PersistenceInfoProvider.cs in helperclasses to true.

Frans Bouma | Lead developer LLBLGen Pro
astrouk
User
Posts: 53
Joined: 13-Jun-2006
# Posted on: 01-Jun-2007 22:03:13   

Otis wrote:

If you can't wait for the fix, please manually set the field's sourcecolumnisnullable flag in PersistenceInfoProvider.cs in helperclasses to true.

Thank you, Frans. I have already done itsimple_smile When do you plan to release next version of runtime lib?

Alex

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 01-Jun-2007 23:01:13   

astrouk wrote:

Otis wrote:

If you can't wait for the fix, please manually set the field's sourcecolumnisnullable flag in PersistenceInfoProvider.cs in helperclasses to true.

Thank you, Frans. I have already done itsimple_smile When do you plan to release next version of runtime lib?

Alex

Probably early next week.

Frans Bouma | Lead developer LLBLGen Pro
absintpm
User
Posts: 22
Joined: 12-Jun-2007
# Posted on: 29-Jul-2008 18:20:07   

Has this been fixed yet? I am using LLBLGen Pro v2.6 (downloaded a couple days back) and I still have some problems with this. Let me explain my scenario: I have a couple SQL databases that must use few common tables. I've moved my tables to a new database, I've replaced them with views that are reading/writing in the common database and I regenerated the LLBLGen, re-mapping the entities to the views. Now: 1) It would of been nice to preserve (or at least ask to) my relations mapped on other entities. 2) Every time I am re-generating the project the "Is Nullable" value generated in PersistenceInfoProvider.cs for entities mapped on views is "false" regardless of the settings in the designer.

I am not very experimented with LLBLGen yet so maybe I am doing something wrong. Could you advise please?

Thanks.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 30-Jul-2008 11:12:11   

The fix has been available since the last post on this thread.

Please create a new thread and re-open an old thread as the forum guidelines states.

1) It would of been nice to preserve (or at least ask to) my relations mapped on other entities.

The entities were removed from the database so were the realtions. Then you have created views as a replacement, but the Designer can't guess your intentions, to the Designer these are new views, and nothing can relate them to the removed entities/tables.

2) Every time I am re-generating the project the "Is Nullable" value generated in PersistenceInfoProvider.cs for entities mapped on views is "false" regardless of the settings in the designer.

Please post the corresponding code line from the PersistenceInfoProvider.cs Would you please refresh the catalog and re-generate the code.