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
Equalsverifier always throw AssertionError on compare entities with Collection field #816
Comments
Version 3.12 (see Changelog) introduced a check for lazy fields. In your case, In your case, I see you're using Lombok, and you actively exclude the lazy field. I don't understand why it still tries to reference |
Thank you for your response Also I want to know why you compare two same objects in JpaLazyGetterFieldCheck.java? In older versions of this file you compare two different objects which acquired with different methods |
It's good that your classes have getters, but that's not what matters. What matters, is that JpaLazyGetterFieldCheck compares identical objects because its purpose is to see if calling equals causes an exception to be thrown. If the objects are unequal, you risk that not all lazy fields are inspected for this exception, because equals might return early if one of the fields is false. JpaLazyGetterFieldCheck does exactly what it must do. In your case, I see that EqualsVerifier says that you have a lazy field ( If inspecting the output of delombok doesn't help, I recommend that you put the delomboked Java code somewhere and run EqualsVerifier on that, and see with the debugger where the reference to |
I've just released EqualsVerifier 3.15, where using getters in equals is always required for |
Tested with equalsverifer version 3.15: @Data
@Table(name = "user")
@Entity
@EqualsAndHashCode(exclude = {
"oneToManyRoleList", "manyToManyRoleList", "manyToOneRole", "oneToOneRole"})
public class User {
@Id
private Long id;
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "role_id")
private List<Role> oneToManyRoleList = new ArrayList<>();
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "user_role_table",
joinColumns = {@JoinColumn(name = "user_id")},
inverseJoinColumns = {@JoinColumn(name = "role_id")}
)
private List<Role> manyToManyRoleList = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "role_id", nullable = false)
private Role manyToOneRole;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "role_id", nullable = false)
private Role oneToOneRole;
} Role.java @Data
@Entity
@EqualsAndHashCode
public class Role {
@Id
private Long id;
@ManyToMany(fetch = FetchType.LAZY)
private List<User> userList;
} UserTest.java class UserTest {
@Test
void userTest() {
Role red = new Role();
Role blue = new Role();
red.setId(1L);
blue.setId(2L);
EqualsVerifier.forClass(User.class)
.withPrefabValues(Role.class, red, blue)
.suppress(Warning.ALL_FIELDS_SHOULD_BE_USED)
.verify();
}
} Error:
User.java (Delombok): public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof User)) return false;
final User other = (User) o;
if (!other.canEqual((Object) this)) return false;
final Object this$id = this.getId();
final Object other$id = other.getId();
if (this$id == null ? other$id != null : !this$id.equals(other$id)) return false;
return true;
}
protected boolean canEqual(final Object other) {
return other instanceof User;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $id = this.getId();
result = result * PRIME + ($id == null ? 43 : $id.hashCode());
return result;
} None of the excluded fields are inside the equals method. |
I'm on vacation right now. I'll look into this when I get back! |
Thanks, I was able to reproduce the issue now. I've just released version 3.15.1 which fixes this! |
Describe the bug
Going Equalsverifier from 3.9 to 3.14.1 and now my tests failed with this error:
java.lang.AssertionError: EqualsVerifier found a problem in class com.myproject.security.service.domain.Client.
-> JPA Entity: direct reference to field clientTypes used in equals instead of getter getClientTypes.
To Reproduce
Client.java
ClientType.java
Code that triggers the behavior
Error message
java.lang.AssertionError: EqualsVerifier found a problem in class com.myproject.security.service.domain.Client.
-> JPA Entity: direct reference to field clientTypes used in equals instead of getter getClientTypes.
For more information, go to: https://www.jqno.nl/equalsverifier/errormessages
(EqualsVerifier 3.14.1, JDK 17.0.2 on Windows 10)
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:62)
at nl.jqno.equalsverifier.internal.checkers.FieldInspector.check(FieldInspector.java:29)
at nl.jqno.equalsverifier.internal.checkers.FieldsChecker.check(FieldsChecker.java:99)
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)
... 70 more
Expected behavior
No AssertionError or another errors
Version
3.14.1
Additional context
Analyzing source code, I found that problem in JpaLazyGetterFieldCheck.java (confirmed with debug). Two objects for comparing create with the same way (using method getRedObject), after these objects compare with equals (I think that result will always true), so after that comparing I always getting error
Also I analyzed older versions of this file and in first version was comparing two different objects, because they was created with different methods (getRedObject and getBlueObject). With debug I created objects with this way and they was absolutely different.
Besides I tried to remove exclude in EqualsAndHashCode annotation. After this my tests finished correctly
The text was updated successfully, but these errors were encountered: