You use Allow Null on a modeled attribute when that attribute may have no value, for example when a customer's middle name or an invoice's paid date has not been supplied yet.
What Allow Null controls
Allow Null is an attribute property in MDriven Designer that controls whether the attribute can hold null (no assigned value).
It affects both:
- The attribute in memory.
- The corresponding database attribute when you create or evolve the database.
In model displays, a nullable type is shown with a question mark (?) after its type, using C# syntax. For example, a nullable Boolean is displayed as Boolean?. When you set Allow Null to false, the question mark disappears.
Choose whether an attribute needs null
Set Allow Null according to what the value means in your domain.
| Attribute example | Allow Null | Why |
|---|---|---|
Invoice.PaidDate
|
true
|
An unpaid invoice has no paid date yet. |
Order.Quantity
|
Usually false
|
A quantity normally requires a value; 0 is a meaningful value that differs from no value.
|
Person.MiddleName
|
true
|
The middle name may not be known or may not exist. |
Task.IsCompleted
|
false when every task must be either completed or not completed
|
A non-nullable Boolean has two states: true and false.
|
Nullability is particularly useful for numeric attributes. For example, 0 can mean that someone entered zero, while null means that no value has been entered yet.
Nullable Boolean values are tri-state
A nullable Boolean can be true, false, or null. Treat these as three distinct states when you write OCL expressions.
For example, an optional DisableEditing value can be null when it has not been decided. Do not assume that comparing a nullable Boolean with false has the same meaning as testing whether editing is enabled. See Not for the nullable-Boolean behavior and recommended expressions.
Set Allow Null
- Select the attribute in your model.
- In the Property Inspector, locate Allow Null.
- Set it to
truewhen the attribute may have no value, orfalsewhen a value is required. - Before evolving a database, review the related Initial value and DefaultDbValue settings.
Database evolution and default values
When Allow Null is false, most database engines need a DefaultDbValue when you evolve the database to add the attribute. Existing database rows need a value for the new non-nullable field; without one, the evolve can fail.
For example, if you add a non-nullable Quantity attribute to an existing table, use a database-formatted default such as 0 before you evolve. If the attribute is nullable, the database can use null for existing rows and a default database value is not needed for that purpose.
Initial value and DefaultDbValue have different roles:
| Property | Used for | Example for a Decimal attribute |
|---|---|---|
| Initial value | The value used in memory for a new object | 0
|
| DefaultDbValue | The database value used when the database is created or evolved | 0
|
| Allow Null | Whether the attribute may have no value in memory and in the database | true or false
|
Read Documentation:Initial values and Default Database values before changing these settings on an attribute that has already been evolved. See Documentation:DefaultDBValue for the database-specific role of DefaultDbValue.
Work with null in OCL
Use OCL null operators rather than comparing a value directly with a typed null value.
| Task | OCL approach | Example |
|---|---|---|
| Test whether a value has no assignment | .isNull
|
self.PaidDate.isNull
|
| Test whether a value is assigned | .notNull
|
self.PaidDate.notNull
|
| Assign or return a typed null | <Type>.nullValue
|
self.PaidDate := Date.nullValue
|
For the test operators, see isNull and notNull. To assign a null value, use nullValue. Do not use <Type>.nullValue as a comparison value.
Strings: distinguish null from empty text
A string can be null or an empty string (). These values can have different meanings: null may mean that no value was supplied, while an empty string may mean that a value was cleared or entered as blank.
When your logic should treat both states as missing text, use the string ->isnullorempty operator. For example, use it when validating that a user has supplied a display name:
self.DisplayName->isnulloremptyPresent null in a picklist
Allowing null in the model does not by itself determine how a ViewModel picklist presents an unselected value. Configure the picklist's Null/NullRep options when you need to hide null, offer it first or last, or show it only before the user selects another value. See Documentation:How Null is represented in your picklist.
See also
- Documentation:Initial values and Default Database values
- Documentation:DefaultDBValue
- Documentation:OCLOperators isNull
- Documentation:OCLOperators nullValue
- Documentation:How Null is represented in your picklist
[[Category:Attributes and data types [Beginner]]
OCL null handling in expressions
OCL null handling in expressions
You can test modeled null values and convert nullable numbers to non-null numeric values when writing OCL expressions.
A nullable attribute has no assigned value when it is null. For example, self.PaidDate.isNull tests whether an invoice has no paid date.
Test a nullable value
Use .isNull and .notNull to test a value before applying logic that depends on it.
| Purpose | Expression | Example |
|---|---|---|
| Test for no assigned value | .isNull
|
self.PaidDate.isNull
|
| Test for an assigned value | .notNull
|
self.PaidDate.notNull
|
| Return or assign a typed null | <Type>.nullValue
|
self.PaidDate := Date.nullValue
|
Do not use <Type>.nullValue as a comparison value. Use isNull or notNull instead.
Handle nullable numbers in collections
Use .Value when an expression requires a non-null numeric result. For a nullable number, .Value returns its assigned underlying value; when no underlying value is assigned, it returns 0.
For example, calculate a total from nullable product prices:
Product.allinstances.Price->sum.ValueYou can also collect a non-null value for each product before summing:
Product.allinstances->collect(i|i.Price.Value)->sumThe select operator evaluates a Boolean expression for each iterated object. Use a loop variable to make the tested value explicit. For example, this selects products whose Price has an assigned value:
Product.allinstances->select(i|i.Price.notNull)See value for nullable numeric values and Expressions for collection loop variables and select.
Strings: null and empty text
A string can be null or an empty string (). When both states mean missing text, use ->isnullorempty.
self.DisplayName->isnulloremptyAttribute chains and OCL result states
The behavior of chained attribute access when an intermediate object is null, such as self.Parent.Manager.Salary, is not defined on this page. Do not infer that a chain returns null, undefined, or invalid from the attribute's Allow Null setting.
Likewise, this page does not define null propagation for ->select, ->collect, or ->any, or define the distinction between null, undefined, and invalid. Confirm these evaluation rules for the MDriven version you use before relying on them in constraints, derived attributes, or ViewModel expressions.
