Skip to content

Commit

Permalink
Merge pull request #893 from jqno/jpa-lazy-generated-id
Browse files Browse the repository at this point in the history
Checks getter usage for generated id fields
  • Loading branch information
jqno authored Dec 22, 2023
2 parents 8861c02 + 73b5b5e commit b237314
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 28 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Check that getters are used for all generated JPA id fields. ([Issue 892](https://github.com/jqno/equalsverifier/issues/892))

## [3.15.4] - 2023-11-29

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private void assertEntity(
) {
assertTrue(
Formatter.of(
"JPA Entity: direct reference to field %% used in %% instead of getter %%.",
"JPA Entity: direct reference to field %% used in %% instead of getter %%().",
fieldName,
method,
getterName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,13 @@ public void postProcess(Set<Class<?>> types, AnnotationCache annotationCache) {
"javax.persistence.ManyToOne",
"javax.persistence.ManyToMany",
"javax.persistence.ElementCollection",
"javax.persistence.GeneratedValue",
"jakarta.persistence.OneToOne",
"jakarta.persistence.OneToMany",
"jakarta.persistence.ManyToOne",
"jakarta.persistence.ManyToMany",
"jakarta.persistence.ElementCollection"
"jakarta.persistence.ElementCollection",
"jakarta.persistence.GeneratedValue"
),

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
package nl.jqno.equalsverifier.integration.extra_features;

import jakarta.persistence.Basic;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.*;
import java.util.Arrays;
import java.util.Objects;
import nl.jqno.equalsverifier.EqualsVerifier;
Expand Down Expand Up @@ -53,7 +46,7 @@ public void basicGetterNotUsed_givenWarningSuppressed() {
}

@Test
public void basicGetterUsed_givenAnnotationIsOnGetter() {
public void basicGetterNotUsed_givenAnnotationIsOnGetter() {
getterNotUsed(IncorrectBasicJakartaLazyGetterContainer.class, "equals");
getterNotUsed_warningSuppressed(IncorrectBasicJakartaLazyGetterContainer.class);
}
Expand Down Expand Up @@ -148,17 +141,48 @@ public void differentCodingStyle_multiple() {
.verify();
}

private void getterNotUsed(Class<?> type, String method) {
@Test
public void getterUsedForGeneratedId() {
EqualsVerifier
.forClass(CorrectGeneratedJpaIdContainer.class)
.suppress(Warning.SURROGATE_KEY)
.verify();
EqualsVerifier
.forClass(CorrectGeneratedJpaIdContainer.class)
.suppress(Warning.SURROGATE_OR_BUSINESS_KEY)
.verify();
}

@Test
public void getterNotUsedForGeneratedId() {
getterNotUsed(IncorrectGeneratedJpaIdContainer.class, "equals", Warning.SURROGATE_KEY);
getterNotUsed_warningSuppressed(
IncorrectGeneratedJpaIdContainer.class,
Warning.SURROGATE_KEY
);
getterNotUsed(
IncorrectGeneratedJpaIdContainer.class,
"equals",
Warning.SURROGATE_OR_BUSINESS_KEY
);
getterNotUsed_warningSuppressed(
IncorrectGeneratedJpaIdContainer.class,
Warning.SURROGATE_OR_BUSINESS_KEY
);
}

private void getterNotUsed(Class<?> type, String method, Warning... additionalWarnings) {
ExpectedException
.when(() -> EqualsVerifier.forClass(type).suppress(Warning.NONFINAL_FIELDS).verify())
.when(() -> EqualsVerifier.forClass(type).suppress(additionalWarnings).verify())
.assertFailure()
.assertMessageContains("JPA Entity", method, "direct reference");
}

private void getterNotUsed_warningSuppressed(Class<?> type) {
private void getterNotUsed_warningSuppressed(Class<?> type, Warning... additionalWarnings) {
EqualsVerifier
.forClass(type)
.suppress(Warning.JPA_GETTER, Warning.NONFINAL_FIELDS)
.suppress(Warning.JPA_GETTER)
.suppress(additionalWarnings)
.verify();
}

Expand Down Expand Up @@ -612,4 +636,56 @@ public int hashCode() {
return Objects.hash(getOneToMany(), getManyToOne());
}
}

@Entity
static class CorrectGeneratedJpaIdContainer {

@Id
@GeneratedValue
private String id;

public String getId() {
return id;
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof CorrectGeneratedJpaIdContainer)) {
return false;
}
CorrectGeneratedJpaIdContainer other = (CorrectGeneratedJpaIdContainer) obj;
return Objects.equals(getId(), other.getId());
}

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

@Entity
static class IncorrectGeneratedJpaIdContainer {

@Id
@GeneratedValue
private String id;

public String getId() {
return id;
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof IncorrectGeneratedJpaIdContainer)) {
return false;
}
IncorrectGeneratedJpaIdContainer other = (IncorrectGeneratedJpaIdContainer) obj;
return Objects.equals(id, other.id);
}

@Override
public int hashCode() {
return Objects.hash(getId());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,7 @@
import nl.jqno.equalsverifier.EqualsVerifier;
import nl.jqno.equalsverifier.Warning;
import nl.jqno.equalsverifier.internal.testhelpers.ExpectedException;
import nl.jqno.equalsverifier.testhelpers.annotations.javax.persistence.Basic;
import nl.jqno.equalsverifier.testhelpers.annotations.javax.persistence.ElementCollection;
import nl.jqno.equalsverifier.testhelpers.annotations.javax.persistence.Entity;
import nl.jqno.equalsverifier.testhelpers.annotations.javax.persistence.FetchType;
import nl.jqno.equalsverifier.testhelpers.annotations.javax.persistence.ManyToMany;
import nl.jqno.equalsverifier.testhelpers.annotations.javax.persistence.ManyToOne;
import nl.jqno.equalsverifier.testhelpers.annotations.javax.persistence.OneToMany;
import nl.jqno.equalsverifier.testhelpers.annotations.javax.persistence.OneToOne;
import nl.jqno.equalsverifier.testhelpers.annotations.javax.persistence.*;
import org.junit.jupiter.api.Test;

// CHECKSTYLE OFF: HiddenField
Expand Down Expand Up @@ -46,7 +39,7 @@ public void basicGetterNotUsed_givenWarningSuppressed() {
}

@Test
public void basicGetterUsed_givenAnnotationIsOnGetter() {
public void basicGetterNotUsed_givenAnnotationIsOnGetter() {
getterNotUsed(IncorrectBasicJpaLazyGetterContainer.class, "equals");
getterNotUsed_warningSuppressed(IncorrectBasicJpaLazyGetterContainer.class);
}
Expand Down Expand Up @@ -138,15 +131,49 @@ public void differentCodingStyle_multiple() {
.verify();
}

private void getterNotUsed(Class<?> type, String method) {
@Test
public void getterUsedForGeneratedId() {
EqualsVerifier
.forClass(CorrectGeneratedJpaIdContainer.class)
.suppress(Warning.SURROGATE_KEY)
.verify();
EqualsVerifier
.forClass(CorrectGeneratedJpaIdContainer.class)
.suppress(Warning.SURROGATE_OR_BUSINESS_KEY)
.verify();
}

@Test
public void getterNotUsedForGeneratedId() {
getterNotUsed(IncorrectGeneratedJpaIdContainer.class, "equals", Warning.SURROGATE_KEY);
getterNotUsed_warningSuppressed(
IncorrectGeneratedJpaIdContainer.class,
Warning.SURROGATE_KEY
);
getterNotUsed(
IncorrectGeneratedJpaIdContainer.class,
"equals",
Warning.SURROGATE_OR_BUSINESS_KEY
);
getterNotUsed_warningSuppressed(
IncorrectGeneratedJpaIdContainer.class,
Warning.SURROGATE_OR_BUSINESS_KEY
);
}

private void getterNotUsed(Class<?> type, String method, Warning... additionalWarnings) {
ExpectedException
.when(() -> EqualsVerifier.forClass(type).verify())
.when(() -> EqualsVerifier.forClass(type).suppress(additionalWarnings).verify())
.assertFailure()
.assertMessageContains("JPA Entity", method, "direct reference");
}

private void getterNotUsed_warningSuppressed(Class<?> type) {
EqualsVerifier.forClass(type).suppress(Warning.JPA_GETTER).verify();
private void getterNotUsed_warningSuppressed(Class<?> type, Warning... additionalWarnings) {
EqualsVerifier
.forClass(type)
.suppress(Warning.JPA_GETTER)
.suppress(additionalWarnings)
.verify();
}

@Entity
Expand Down Expand Up @@ -596,4 +623,56 @@ public int hashCode() {
return Objects.hash(getOneToMany(), getManyToOne());
}
}

@Entity
static class CorrectGeneratedJpaIdContainer {

@Id
@GeneratedValue
private String id;

public String getId() {
return id;
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof CorrectGeneratedJpaIdContainer)) {
return false;
}
CorrectGeneratedJpaIdContainer other = (CorrectGeneratedJpaIdContainer) obj;
return Objects.equals(getId(), other.getId());
}

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

@Entity
static class IncorrectGeneratedJpaIdContainer {

@Id
@GeneratedValue
private String id;

public String getId() {
return id;
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof IncorrectGeneratedJpaIdContainer)) {
return false;
}
IncorrectGeneratedJpaIdContainer other = (IncorrectGeneratedJpaIdContainer) obj;
return Objects.equals(id, other.id);
}

@Override
public int hashCode() {
return Objects.hash(getId());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package nl.jqno.equalsverifier.testhelpers.annotations.javax.persistence;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface GeneratedValue {
}

0 comments on commit b237314

Please sign in to comment.