Using natural keys as part of equals and hashCode

I know that this topic has been discussed many times, but some clarifications are still needed on the problem we are facing. Hibernate best practicestalk about using natural keys for equals / hashCode methods. We have a composite key, which consists of 2 parameters (for example, String name, Organization org) to which a certain object belongs. Unfortunately, I cannot use org because it is lazily loaded and leads to other problems, and I also do not want to create a surrogate key (possibly automatically created from a database or UUID, created using an API call before creating the object). What parameters do I have, because the fields in the above objects (name, org) are unique, and I can’t just write my own logic based only on the name field itself. Is a surrogate key the only option, does this mean that I have to store this value as part of each table row?

+3
source share
3 answers

Hibernate's best practices talk about using natural keys for equals / hashCode methods.

Yes, therefore I will not dwell on this in detail.

We have a composite key, which consists of two parameters (for example, String name, Organization org) to which a certain object belongs. Unfortunately, I cannot use org, as it is lazily loaded and leads to other problems.

Could you figure it out a bit and illustrate it with some code? I would like to understand how you did it and what the problem is.

What parameters do I have, because the fields in the above objects (name, org) are unique, and I can’t just write my own logic based only on the name field itself.

, . , org.getId() - , , .

+2

-

public class MyEntity {

    private String name;

    private Organization organization;

    // getter and setter's

    public boolean equals(Object o) {
        if(!(o instanceof MyEntity))
            return false;

        MyEntity other = (MyEntity) o;
        return new EqualsBuilder().append(getName(), other.getName())
                                  .append(getOrganization(), other.getOrganization())
                                  .isEquals();
    }

}

, , Hibernate.isInitialized

public boolean equals(Object o) {
    if(!(o instanceof MyEntity))
        return false;

    MyEntity other = (MyEntity) o;
    boolean equals = new EqualsBuilder().append(getName(), other.getName())
                                        .isEquals();

    if(Hibernate.isInitialized(getOrganization())) {
       // loaded Organization
    } else {
       // supply custom routine
    }

    return equals;
}

-, Hibernate

                                        no eq/hC at all  eq/hC with the id property  eq/hC with buisness key
use in a composite-id                   No               Yes                         Yes
multiple new instances in set           Yes              No                          Yes
equal to same object from other session No               Yes                         Yes
collections intact after saving         Yes              No                          Yes        

:

id:

, - equals/hashCode, == .

:

:

HashSet someSet = new HashSet();
someSet.add(new PersistentClass());
someSet.add(new PersistentClass());
assert(someSet.size() == 2);

, :

:

PersistentClass p1 = sessionOne.load(PersistentClass.class, new Integer(1));
PersistentClass p2 = sessionTwo.load(PersistentClass.class, new Integer(1));
assert(p1.equals(p2));

:

:

HashSet set = new HashSet();
User u = new User();
set.add(u);
session.save(u);
assert(set.contains(u));

Thread, equals/hashCode

+4

, ? , Foo. , foo.getOrganization(), ? FooDAO, , foo ?

Then it will be available later when you need to do something with equals () and hashCode ().

0
source

Source: https://habr.com/ru/post/1766451/


All Articles