We're updating the issue view to help you get more done. 

ComponentType mappings for with value types (structs) cause incorrect dirty checking

Description

If a member of a class is a value type T and mapped as a component, NHibernate will always detect objects with a value of default(T) as dirty.

The problem is in ComponentType.IsDirty(): the original value as ready by NHibernate will be null, whereas the value returned from an instance will be a boxed default(T). The current logic does not treat null as equivalent to default(T) for value types, which it should do.

It is possible in the constructor of ComponentType to box a default(T) and use this instead of null in the IsDirty() methods - this works as expected.

public override bool IsDirty( object x, object y, ISessionImplementor session )
{
if( x == y )
{
return false;
}

// In ComponentType() the object componentClassDefault is
// set to a new instance of componentClass iff componentClass is a value type.
if (x == null && y.Equals(componentClassDefault) ||
y == null && x.Equals(componentClassDefault))
{
return false;
}

if( x == null || y == null )
{
return true;
}

Environment

None

Status

Assignee

Unassigned

Reporter

Nicholas Blumhardt