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

JPALazyGetterFieldCheck failing for inherited fields #744

Closed
jcamerin opened this issue Dec 13, 2022 · 1 comment
Closed

JPALazyGetterFieldCheck failing for inherited fields #744

jcamerin opened this issue Dec 13, 2022 · 1 comment

Comments

@jcamerin
Copy link

The JPALazyGetterFieldCheck is failing on inherited fields when a class with the Entity annotation inherits a field that is lazy loaded from a parent class. I did some debugging and found that the field list include all fields in the class hierarchy, while the code checking getters uses Java reflections declared methods, which will only retrieve methods in the specific class. Thus, EqualsVerifier is not finding the inherited getter.

Below is the stack trace and example code that causes this failure.

java.lang.AssertionError: EqualsVerifier found a problem in class com.messagegears.accelerator.bo.Child.
-> JPA Entity: direct reference to field textContent used in equals instead of getter getTextContent.

For more information, go to: https://www.jqno.nl/equalsverifier/errormessages
(EqualsVerifier 3.12.2, JDK 1.8.0_144 on Mac OS X)

at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verify(SingleTypeEqualsVerifierApi.java:314)
at com.messagegears.accelerator.bo.ChildTest.testEqualsAndHashCode(ChildTest.java:10)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

Caused by: nl.jqno.equalsverifier.internal.exceptions.AssertionException
at nl.jqno.equalsverifier.internal.util.Assert.assertTrue(Assert.java:53)
at nl.jqno.equalsverifier.internal.checkers.fieldchecks.JpaLazyGetterFieldCheck.assertEntity(JpaLazyGetterFieldCheck.java:99)
at nl.jqno.equalsverifier.internal.checkers.fieldchecks.JpaLazyGetterFieldCheck.execute(JpaLazyGetterFieldCheck.java:50)
at nl.jqno.equalsverifier.internal.checkers.FieldInspector.check(FieldInspector.java:29)
at nl.jqno.equalsverifier.internal.checkers.FieldsChecker.check(FieldsChecker.java:95)
at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verifyWithExamples(SingleTypeEqualsVerifierApi.java:430)
at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.performVerification(SingleTypeEqualsVerifierApi.java:385)
at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verify(SingleTypeEqualsVerifierApi.java:312)
... 28 more

import java.util.Objects;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;

@entity
public class Parent {
@column(name = "text_content")
@basic(fetch = FetchType.LAZY)
private String textContent;

public String getTextContent() {
    return textContent;
}

public void setTextContent(final String textContent) {
    this.textContent = textContent;
}

@Override
public boolean equals(final Object o) {
    if (this == o) {
        return true;
    }
    if (o == null || getClass() != o.getClass()) {
        return false;
    }
    final Parent parent = (Parent) o;
    return Objects.equals(getTextContent(), parent.getTextContent());
}

@Override
public int hashCode() {
    return Objects.hash(getTextContent());
}

}

import java.util.Objects;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;

@entity
public class Child extends Parent {

@Column(name = "child_content")
@Basic(fetch = FetchType.LAZY)
private String childContent;

public String getChildContent() {
    return childContent;
}

public void setChildContent(final String childContent) {
    this.childContent = childContent;
}

@Override public boolean equals(final Object o) {
    if (this == o) {
        return true;
    }
    if (o == null || getClass() != o.getClass()) {
        return false;
    }
    if (!super.equals(o)) {
        return false;
    }
    final Child child = (Child) o;
    return Objects.equals(getChildContent(), child.getChildContent());
}

@Override public int hashCode() {
    return Objects.hash(super.hashCode(), getChildContent());
}

}

import nl.jqno.equalsverifier.EqualsVerifier;
import org.junit.Test;

public class ChildTest {

@Test
public void testEqualsAndHashCode() {
    EqualsVerifier.forClass(Child.class).usingGetClass().verify();
}

}

@jqno
Copy link
Owner

jqno commented Dec 14, 2022

Thanks for letting me know! Fortunately it was an easy fix. I've made a new release: version 3.12.3 which is syncing with Maven Central right now.

@jqno jqno closed this as completed Dec 14, 2022
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

2 participants