Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle null when comparing equality of value objects?

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:

  1. This is the behaviour of Equals() when you use a C# struct instead of a class and do not override Equals().

  2. 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?

like image 962
Marco Eckstein Avatar asked Nov 15 '22 05:11

Marco Eckstein


1 Answers

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.

like image 157
Diego Mijelshon Avatar answered Dec 05 '22 05:12

Diego Mijelshon