Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using SURROGATE_OR_BUSINESS_KEY in the business key for equals JPA_GETTER should be enforced. #892

Closed
Moritz-Hoeppner opened this issue Dec 13, 2023 · 3 comments

Comments

@Moritz-Hoeppner
Copy link

Moritz-Hoeppner commented Dec 13, 2023

Describe the bug
I had a bug in my project where equals used .id instead of .getId() when comparing the IDs of an Object. The .id just returned null while .getId returned the correct value. I believe that for surrogate key equals, the getters should be enforced.

To Reproduce

Code that triggers the behavior
Equals Method:

 @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof MyEntity that)) {
            return false;
        }
        return id != null && id.equals(that.id);
    }

The test should make sure to use
return id != null && id.equals(that.**getId()**); instead

Test that passed:

@Test
    void testEquals() {
        EqualsVerifier
            .forClass(MyEntity.class)
            .withPrefabValues(Set.class, Set.of(new MyEntity()), Set.of(new MyEntity()))
            .suppress(Warning.SURROGATE_KEY)
            .suppress(Warning.IDENTICAL_COPY_FOR_VERSIONED_ENTITY)
            .suppress(Warning.STRICT_HASHCODE)
            .verify();
    }

Remember, you have the problem right in front of you. I have to try and reproduce it in my spare time. Please help me, so that I can help you!

Error message
The test is passing so no error message. Also no warning.

Expected behavior
I would expect the test to fail. But it did not.

Version
3.15.4

Additional context
According to this blog post, the equals should also be implemented using getId() : https://thorben-janssen.com/ultimate-guide-to-implementing-equals-and-hashcode-with-hibernate/

@jqno
Copy link
Owner

jqno commented Dec 14, 2023

Am I correct in assuming you're referring to the "Using a Generated Primary Key" section of that blog post, where the id is generated by Hibernate and is only available once the entity is persisted?

Can you describe the circumstances when entity's id field is null, but getId() isn't? When exactly does that happen?

@MoritzOtto
Copy link

Hey jqno,
we do have the Problem, if the Entity is "lazy" loaded and a HibernateProxyElement got created. The easiest way to create this is calling the getReferenceById() Method by Spring Boot.
When doing this JPA acts the same way then reference a relationship described here: https://jqno.nl/equalsverifier/errormessages/jpa-direct-reference-instead-of-getter/
Hope this helps already...

@jqno
Copy link
Owner

jqno commented Dec 22, 2023

Thanks for the update, and sorry for the slow replies - it's been a busy week.

I've released version 3.15.5, and updated the documentation page you reference as well.

@jqno jqno closed this as completed Dec 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants