Skip to content

Equals is ignored for Components that contain collection #3539

Open
@DmitryMak

Description

@DmitryMak

NHibernate ignores Equals implementation on Components when they contain a collection. As a result, it issues an unnecessary DELETE followed by multiple INSERTs. It basically recreates all rows that were backing the collection even though the collection has not changed.

Example:


<class name="Person">
    <component name="CreditInfo">
        <bag name="OldCards" cascade="all" >
            <key column="PersonId" />
                ...


class Person {
    public CreditInfo CreditInfo;
}

public class CreditInfo {
    public readonly ICollection<String> OldCards;

    public CreditInfo(IEnumerable<String> oldCards) {        
        OldCards = new List<String>(oldCards);
    }
    
    public override Boolean Equals(Object obj) {

        var other = (CreditInfo)obj;
        return OldCards.SequenceEqual(other.OldCards);  <-- No changes detected by Equals!
    }
}

 
person.CreditInfo = new CreditInfo(person.CreditInfo.OldCards);  <-- effectively cloned

// will DELETE all card rows and INSERT all of them again even though CreditInfo did not change

I think there are 2 counterintuitive behaviors here:

  1. Why is NHibernate ignoring CreditInfo.Equals? The method tells it that the component (value type) has not changed. A very common immutable Value Object scenario. Why does it have to go 'inside' the component?

  2. Replacing NHibernate collection (backing OldCards) with a new collection with the same items seem to make NHibernate delete and reinsert all rows. Is there a way to implement value equality on collections, think SequenceEquals?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions