Note: I use C# as an example, but the problem is virtually the same in Java and probably many other languages.
Assume you implement a value object (as in value object pattern by M. Fowler) and it has some nullable field:
class MyValueObject
{
// Nullable field (with public access to keep the example short):
public string MyField;
}
Then, when overriding Equals(), how do you treat the case when both value objects have their MyField set to null? Are they equal or not?
In C#, treating them as equal seems obvious, because:
This is the behaviour of Equals() when you use a C# struct instead of a class and do not override Equals().
The following expressions are true:
null == null
object.ReferenceEquals(null, null)
object.Equals(null, null)
However, in SQL (at least in SQL Server's dialect), NULL = NULL
is false, whereas NULL is NULL
is true.
I am wondering what implementation is expected when using an O/R mapper (in my case, NHibernate). If you implement the "natural" C# equality semantics, may there be any ill effects when the O/R mapper maps them to the database?
Or maybe allowing nullable fields in value objects is wrong anyway?
Since ORMs know the relational model, they usually expose a way to query using SQL semantics.
NHibernate, for example, provides the is [not] null
operator in HQL, and Restrictions.Is[Not]Null
in Criteria.
Of course, there's an API where these paradigms collide: LINQ. Most ORMs try to do the right thing when comparing to null (i.e. replacing with is null
), although there can be issues some times, especially where the behavior is not obvious.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With