Problems with null fields and default values

Posts   
 
    
ElQueso avatar
ElQueso
User
Posts: 27
Joined: 08-Oct-2005
# Posted on: 06-Sep-2007 18:39:17   

I have (well, had simple_smile ) an issue with how Gen Pro (2.5) entities handle fields that aren't nullable in a database field, using data types that are not nullable. In my particular case, I have a field of data type int, which of course in the entity defaults to 0.

I have a grid in which I am entering data. To give it context, I am entering sections of depths of a well bore, to describe properties pertaining to those specific depths. The first depth starts at 0, and goes down X feet. Therefore, I actually want the first StartDepth, which is an integer, to be 0. It defaults to this value, so I leave it alone and enter the EndDepth and go on to the next record, etc.

Problem is, when I go to save the data, I get an SQL error that tells me that the StartDepth field cannot be null. Obviously, the entity is carrying the DBValue as null. If I change the StartDepth field to anything other than 0, then back to 0, of course, it works fine.

Ok, so I got to this point and realized that I didn't have the field defaulted to anything in the database. When I went to the table and defaulted the field to 0, Gen Pro behaves well in this respect because the insert query does not try to insert a null into the field, instead allowing the database to insert the default value in the field. So when I save, I don't have the problem mentioned.

So then this raises another possible related issue. Gen Pro does not look at the Default property of the field in the database, or allow the user in the designer to set a default value for a field (that I'm aware of). It uses the default value for the given property's data type. So, for example, if I were to solve my problem above by putting in a default value, as long as it is 0, matching an int's default value in GenPro, I'm ok. But if I were to put, say, 1 (or 5, etc), and allow 0 as a valid value (in other words, not creating a validation problem with 0), then the field would default to Gen Pro's 0 for an int field, display that to the user, who would not change it, and then when the user saves it, the field would revert to the default value in the database.

The only real problem I have with this is that the user may not see this change in value if the form that displays the data is no longer open when the data is saved (or if, as is often the case, the user is not very observant). If the form is open, the field visually reverts to the default value that is in the database after the save and the user can notice that and change it back, although possibly with some aggravation.

Now, this is not necessarily a huge issue by any means. I don't know that I would ever put some default value on an int, for example, other than 0 (but I'm sure it's not unreasonable to think it may be needed), but since I'd started writing about an issue I thought I had, then realized how to correct it, that I'd go ahead and post on this part of it as well.

Is it possible to grab the default value from the database and use it instead of the Gen Pro default type value? Is there a reason not to? Again, just curious at this point, not a big deal, but something that might keep someone from having an unexpected issue somewhere down the line.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 07-Sep-2007 09:55:34   

First let's discuss the main issue:

Inputs: 1- You have a non-nullable field in the database, without a default value. 2- LLBLGen Pro doesn't attempt to set a field in an Insert or Update statement if that field's value hasn't been changed.

Solution: 1- Use a database default value. (as you did). 2- Use entity validation (before saving, and manually set the field, or set it's IsChanged flag to true). Personally I recommend the second option.

Now let's discuss the other issue:

Inputs: 1- You have a field in the database with a default value, other than the corresponding .NET type default value. (let's stick to the "5" example) 2- You want the user to see the default value in the Inserting Form.

Solution: Taking into consideration that Default Values may be changed over time.

I see no better solution than to manually specify default values in a configuration file, where you pick them up in the Loading event of your Insert Form.

I don't recommend hard-coding them either in the generated code or your application code. And I don't recommend accessing the database every time (at runtime), to grab the current default value for each field.

arschr
User
Posts: 893
Joined: 14-Dec-2003
# Posted on: 07-Sep-2007 13:22:37   

I see no better solution than to manually specify default values in a configuration file, where you pick them up in the Loading event of your Insert Form.

Wouldn't a better solution be for LlblGen to pick up the deterministic defaults on project request, and provide a way to make them available at the client?

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 07-Sep-2007 16:34:06   

Wouldn't a better solution be for LlblGen to pick up the deterministic defaults on project request, and provide a way to make them available at the client?

At design time or at runtime?

arschr
User
Posts: 893
Joined: 14-Dec-2003
# Posted on: 07-Sep-2007 17:07:44   

They would be available for use at runtime.

Posts: 254
Joined: 16-Nov-2006
# Posted on: 09-Sep-2007 00:30:22   

It would be very useful to have the default values for fields of entities available at runtime and be captured at design time when the catalog is refreshed

ElQueso avatar
ElQueso
User
Posts: 27
Joined: 08-Oct-2005
# Posted on: 10-Sep-2007 09:29:40   

Walaa wrote:

First let's discuss the main issue:

Inputs: 1- You have a non-nullable field in the database, without a default value. 2- LLBLGen Pro doesn't attempt to set a field in an Insert or Update statement if that field's value hasn't been changed.

Solution: 1- Use a database default value. (as you did). 2- Use entity validation (before saving, and manually set the field, or set it's IsChanged flag to true). Personally I recommend the second option.

Seems to me that solution #2 is hardcoding defaults, if I understand what you're saying.

Walaa wrote:

Now let's discuss the other issue:

Inputs: 1- You have a field in the database with a default value, other than the corresponding .NET type default value. (let's stick to the "5" example) 2- You want the user to see the default value in the Inserting Form.

Solution: Taking into consideration that Default Values may be changed over time.

I see no better solution than to manually specify default values in a configuration file, where you pick them up in the Loading event of your Insert Form.

I don't recommend hard-coding them either in the generated code or your application code. And I don't recommend accessing the database every time (at runtime), to grab the current default value for each field.

Manually specifying default values in a configuration file seems like a momentous task, to be honest. The particular application which I am referring to in these posts is quite large (the database contains 131 tables) and the thought of covering default values amongst all of those tables in a config file, and then writing code to handle setting defaults according to those defaults, even with some good generic classes, seems very onerous.

I agree about hard-coding them in the application code. However, the default values are hardcoded in my database script, and therefore the database, which, in my opinion, is where they belong. As such, they are much the same, I would think, as a constraint or a field definition.

I wasn't talking about GenPro getting the default values at runtime - I agree that is not a good solution either. Rather, I was talking about GenPro generating the default values in the entity classes rather than using standard type-specific defaults where a default value is specified in the database. While this is GenPro hardcoding defaults, it's not the same as me creating, for example, partial classes and attempting to hardcode all of my default values.

Of course default values can change over time, but as well, field definitions and constraints, etc can change over time as design requirements dictate this. I would consider a default value to be a data design issue, and therefore if I was changing the default values at design time, and GenPro could pick up on these changes and implement them in my entities when I regenerate, that would be optimum it seems. simple_smile

The runtime issue I was referring to is what currently occurs - I wasn't trying to suggest GenPro actually do anything with the database at runtime, but picking up on default values at design time would provide a runtime solution without accessing the database. If I have a default value in the database set for an int field as 5, at runtime the value defaults to 0 in my bound control (the default value for an integer in GenPro), and if the user does not change the value, AFTER the save occurs and the entity is refetched, the value displayed is 5, not 0 which the user intended to be in there (and as long as there is no validation issue, that should ok).

JimFoye avatar
JimFoye
User
Posts: 656
Joined: 22-Jun-2004
# Posted on: 11-Sep-2007 06:55:34   

I have wondered about this a few times myself. A default is declared in the database much like a constraint. Presumably it is pretty much static (if it is not, then it should not be declared in the database and instead managed in business logic). I, for one, don't go changing defaults very often in my schema, and in any event am used to regenerating the DAL often during development as the schema does change a lot anyway.

I can see an advantage to the designer picking up the default and optionally generating into the DAL code. I wonder if Frans has had this request before and what his thoughts are on it.

arschr
User
Posts: 893
Joined: 14-Dec-2003
# Posted on: 11-Sep-2007 14:19:19   

I wonder if Frans has had this request before

Yes.

and what his thoughts are on it.

As I recall he feels that the ability to set defaults in the database like GetDate(), makes having the knowledge of what the default is via llblgen problimatic.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 11-Sep-2007 14:53:24   

arschr wrote:

I wonder if Frans has had this request before

Yes.

and what his thoughts are on it.

As I recall he feels that the ability to set defaults in the database like GetDate(), makes having the knowledge of what the default is via llblgen problimatic.

GetDate() is perhaps parseable, a complex expression in the native SQL dialect of the DB used isn't. That's the reason: it's simply impossible to determine what the value will be in all cases.

So you have a choice: set the default value in the DB and you'll get the value set when the entity is inserted AND the field is NULL, OR set the default value in entity code.

What the default value should be: it is up to you, so the easiest way is to specify it in code, simply because it's 1 line of code per field, while in the designer it might be a bit more time consuming and also, will likely require a DSL which is language independent because some code isn't usable in VB.NET and is in C# and vice versa.

Frans Bouma | Lead developer LLBLGen Pro