diff --git a/equalsverifier-core/src/main/java/nl/jqno/equalsverifier/internal/checkers/fieldchecks/JpaLazyGetterFieldCheck.java b/equalsverifier-core/src/main/java/nl/jqno/equalsverifier/internal/checkers/fieldchecks/JpaLazyGetterFieldCheck.java index 5f86da9ec..0e3d66605 100644 --- a/equalsverifier-core/src/main/java/nl/jqno/equalsverifier/internal/checkers/fieldchecks/JpaLazyGetterFieldCheck.java +++ b/equalsverifier-core/src/main/java/nl/jqno/equalsverifier/internal/checkers/fieldchecks/JpaLazyGetterFieldCheck.java @@ -4,7 +4,6 @@ import static net.bytebuddy.matcher.ElementMatchers.named; import static nl.jqno.equalsverifier.internal.util.Assert.assertTrue; -import java.util.Set; import java.util.function.Function; import nl.jqno.equalsverifier.internal.exceptions.EqualsVerifierInternalBugException; import nl.jqno.equalsverifier.internal.prefabvalues.PrefabValues; @@ -22,18 +21,18 @@ public class JpaLazyGetterFieldCheck implements FieldCheck { private final Class type; private final ClassAccessor accessor; - private final Set ignoredFields; private final PrefabValues prefabValues; private final AnnotationCache annotationCache; private final Function fieldnameToGetter; + private final TypeTag typeTag; public JpaLazyGetterFieldCheck(Configuration config) { this.type = config.getType(); this.accessor = config.getClassAccessor(); - this.ignoredFields = config.getIgnoredFields(); this.prefabValues = config.getPrefabValues(); this.annotationCache = config.getAnnotationCache(); this.fieldnameToGetter = config.getFieldnameToGetter(); + this.typeTag = config.getTypeTag(); } @Override @@ -45,7 +44,10 @@ public void execute( String fieldName = fieldAccessor.getFieldName(); String getterName = fieldnameToGetter.apply(fieldName); - if (ignoredFields.contains(fieldName) || !fieldIsLazy(fieldAccessor)) { + if ( + !fieldIsUsed(referenceAccessor, copyAccessor, fieldAccessor) || + !fieldIsLazy(fieldAccessor) + ) { return; } @@ -72,6 +74,19 @@ public void execute( assertEntity(fieldName, "hashCode", getterName, hashCodeExceptionCaught); } + private boolean fieldIsUsed( + ObjectAccessor referenceAccessor, + ObjectAccessor copyAccessor, + FieldAccessor fieldAccessor + ) { + T red = referenceAccessor.get(); + T blue = copyAccessor + .withChangedField(fieldAccessor.getField(), prefabValues, typeTag) + .get(); + + return !red.equals(blue); + } + private boolean fieldIsLazy(FieldAccessor fieldAccessor) { return ( annotationCache.hasFieldAnnotation( diff --git a/equalsverifier-core/src/test/java/nl/jqno/equalsverifier/integration/extra_features/JakartaLazyEntityTest.java b/equalsverifier-core/src/test/java/nl/jqno/equalsverifier/integration/extra_features/JakartaLazyEntityTest.java index bf22a1507..9a577887b 100644 --- a/equalsverifier-core/src/test/java/nl/jqno/equalsverifier/integration/extra_features/JakartaLazyEntityTest.java +++ b/equalsverifier-core/src/test/java/nl/jqno/equalsverifier/integration/extra_features/JakartaLazyEntityTest.java @@ -44,6 +44,14 @@ public void basicGetterNotUsed_givenCorrespondingFieldIgnored() { .verify(); } + @Test + public void basicGetterNotUsed_givenWarningSuppressed() { + EqualsVerifier + .forClass(CorrectBasicJakartaIgnoredLazyFieldContainer.class) + .suppress(Warning.ALL_FIELDS_SHOULD_BE_USED) + .verify(); + } + @Test public void basicGetterUsed_givenAnnotationIsOnGetter() { getterNotUsed(IncorrectBasicJakartaLazyGetterContainer.class, "equals"); diff --git a/equalsverifier-core/src/test/java/nl/jqno/equalsverifier/integration/extra_features/JpaLazyEntityTest.java b/equalsverifier-core/src/test/java/nl/jqno/equalsverifier/integration/extra_features/JpaLazyEntityTest.java index c88b8def3..1cb28215d 100644 --- a/equalsverifier-core/src/test/java/nl/jqno/equalsverifier/integration/extra_features/JpaLazyEntityTest.java +++ b/equalsverifier-core/src/test/java/nl/jqno/equalsverifier/integration/extra_features/JpaLazyEntityTest.java @@ -21,18 +21,12 @@ public class JpaLazyEntityTest { @Test public void gettersAreUsed() { - EqualsVerifier - .forClass(CorrectJpaLazyFieldContainer.class) - .suppress(Warning.NONFINAL_FIELDS) - .verify(); + EqualsVerifier.forClass(CorrectJpaLazyFieldContainer.class).verify(); } @Test public void basicGetterNotUsed_givenEagerLoading() { - EqualsVerifier - .forClass(CorrectBasicJpaEagerFieldContainer.class) - .suppress(Warning.NONFINAL_FIELDS) - .verify(); + EqualsVerifier.forClass(CorrectBasicJpaEagerFieldContainer.class).verify(); } @Test @@ -40,7 +34,14 @@ public void basicGetterNotUsed_givenCorrespondingFieldIgnored() { EqualsVerifier .forClass(CorrectBasicJpaIgnoredLazyFieldContainer.class) .withIgnoredFields("basic") - .suppress(Warning.NONFINAL_FIELDS) + .verify(); + } + + @Test + public void basicGetterNotUsed_givenWarningSuppressed() { + EqualsVerifier + .forClass(CorrectBasicJpaIgnoredLazyFieldContainer.class) + .suppress(Warning.ALL_FIELDS_SHOULD_BE_USED) .verify(); } @@ -102,7 +103,6 @@ public void lazyGettersPickedUpInSuper() { public void differentCodingStyle_single() { EqualsVerifier .forClass(DifferentCodingStyleContainer.class) - .suppress(Warning.NONFINAL_FIELDS) .withFieldnameToGetterConverter(fn -> "get" + Character.toUpperCase(fn.charAt(2)) + fn.substring(3) ) @@ -113,7 +113,6 @@ public void differentCodingStyle_single() { public void differentCodingStyle_configured() { EqualsVerifier .configure() - .suppress(Warning.NONFINAL_FIELDS) .withFieldnameToGetterConverter(fn -> "get" + Character.toUpperCase(fn.charAt(2)) + fn.substring(3) ) @@ -125,7 +124,6 @@ public void differentCodingStyle_configured() { public void differentCodingStyle_multiple() { EqualsVerifier .forClasses(Arrays.asList(DifferentCodingStyleContainer.class)) - .suppress(Warning.NONFINAL_FIELDS) .withFieldnameToGetterConverter(fn -> "get" + Character.toUpperCase(fn.charAt(2)) + fn.substring(3) ) @@ -134,16 +132,13 @@ public void differentCodingStyle_multiple() { private void getterNotUsed(Class type, String method) { ExpectedException - .when(() -> EqualsVerifier.forClass(type).suppress(Warning.NONFINAL_FIELDS).verify()) + .when(() -> EqualsVerifier.forClass(type).verify()) .assertFailure() .assertMessageContains("JPA Entity", method, "direct reference"); } private void getterNotUsed_warningSuppressed(Class type) { - EqualsVerifier - .forClass(type) - .suppress(Warning.JPA_GETTER, Warning.NONFINAL_FIELDS) - .verify(); + EqualsVerifier.forClass(type).suppress(Warning.JPA_GETTER).verify(); } @Entity