Skip to content

Commit

Permalink
Equals method not found on abstract class #709
Browse files Browse the repository at this point in the history
  • Loading branch information
NBerghen authored and vladmihalcea committed Apr 17, 2024
1 parent e16b12f commit 0a98c3f
Show file tree
Hide file tree
Showing 10 changed files with 370 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,11 @@ public boolean areEqual(Object one, Object another) {
(one instanceof Map && another instanceof Map)) {
return Objects.equals(one, another);
}
if (one.getClass().equals(another.getClass()) &&
ReflectionUtils.getDeclaredMethodOrNull(one.getClass(), "equals", Object.class) != null) {
return one.equals(another);
if (one.getClass().equals(another.getClass())) {
Method equalsMethod = ReflectionUtils.getMethodOrNull(one.getClass(), "equals", Object.class);
if (equalsMethod != null && !Object.class.equals(equalsMethod.getDeclaringClass())) {
return one.equals(another);
}
}
return objectMapperWrapper.toJsonNode(objectMapperWrapper.toString(one)).equals(
objectMapperWrapper.toJsonNode(objectMapperWrapper.toString(another))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,39 @@ public void testSetsAreEqual() {
assertTrue(descriptor.areEqual(theFirst, theSecond));
}

/**
* When the JSON object contains an explicit equals method, even when defined on the abstract super class {@link AbstractForm},
* that equals method should be used.
* If JSON serialization is used,
* the {@link JsonTypeDescriptor#areEqual(Object, Object)} depends on the values of the fields.
*
* The equals method of the {@link FormImpl} always returns true, so the two objects should be equal,
* even when having a different value.
*/
@Test
public void testAbstractClassImplementationsAreEqual() {
JsonTypeDescriptor descriptor = new JsonTypeDescriptor();

FormImpl firstEntity = new FormImpl("value1");
FormImpl secondEntity = new FormImpl("value2");

assertTrue(descriptor.areEqual(firstEntity, secondEntity));
}

/**
* When the JSON object does not contain an explicit equals method, it should not use the equals method {@link Object},
* but should use the ObjectWrapperMapper to equal the objects as JsonNodes
*/
@Test
public void testClassesWithoutEqualsMethodShouldEqualAsJsonNodes() {
JsonTypeDescriptor descriptor = new JsonTypeDescriptor();

FormWithoutEqualsMethod firstEntity = new FormWithoutEqualsMethod("value1");
FormWithoutEqualsMethod secondEntity = new FormWithoutEqualsMethod("value1");

assertTrue(descriptor.areEqual(firstEntity, secondEntity));
}

@Test
public void testNullPropertyType() {
JsonTypeDescriptor descriptor = new JsonTypeDescriptor();
Expand Down Expand Up @@ -120,4 +153,40 @@ public int hashCode() {
return Objects.hash(formFields);
}
}

private static class FormImpl extends AbstractForm {
private FormImpl(String value) {
super(value);
}
}

private static abstract class AbstractForm {
private String value;

private AbstractForm(String value) {
this.value = value;
}

@Override
public boolean equals(Object o) {
return true;
}

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

private static class FormWithoutEqualsMethod {
private String value;

public String getValue() {
return value;
}

private FormWithoutEqualsMethod(String value) {
this.value = value;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,11 @@ public boolean areEqual(Object one, Object another) {
(one instanceof Map && another instanceof Map)) {
return Objects.equals(one, another);
}
if (one.getClass().equals(another.getClass()) &&
ReflectionUtils.getDeclaredMethodOrNull(one.getClass(), "equals", Object.class) != null) {
return one.equals(another);
if (one.getClass().equals(another.getClass())) {
Method equalsMethod = ReflectionUtils.getMethodOrNull(one.getClass(), "equals", Object.class);
if (equalsMethod != null && !Object.class.equals(equalsMethod.getDeclaringClass())) {
return one.equals(another);
}
}
return objectMapperWrapper.toJsonNode(objectMapperWrapper.toString(one)).equals(
objectMapperWrapper.toJsonNode(objectMapperWrapper.toString(another))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,39 @@ public void testSetsAreEqual() {
assertTrue(descriptor.areEqual(theFirst, theSecond));
}

/**
* When the JSON object contains an explicit equals method, even when defined on the abstract super class {@link AbstractForm},
* that equals method should be used.
* If JSON serialization is used,
* the {@link JsonTypeDescriptor#areEqual(Object, Object)} depends on the values of the fields.
*
* The equals method of the {@link FormImpl} always returns true, so the two objects should be equal,
* even when having a different value.
*/
@Test
public void testAbstractClassImplementationsAreEqual() {
JsonTypeDescriptor descriptor = new JsonTypeDescriptor();

FormImpl firstEntity = new FormImpl("value1");
FormImpl secondEntity = new FormImpl("value2");

assertTrue(descriptor.areEqual(firstEntity, secondEntity));
}

/**
* When the JSON object does not contain an explicit equals method, it should not use the equals method {@link Object},
* but should use the ObjectWrapperMapper to equal the objects as JsonNodes
*/
@Test
public void testClassesWithoutEqualsMethodShouldEqualAsJsonNodes() {
JsonTypeDescriptor descriptor = new JsonTypeDescriptor();

FormWithoutEqualsMethod firstEntity = new FormWithoutEqualsMethod("value1");
FormWithoutEqualsMethod secondEntity = new FormWithoutEqualsMethod("value1");

assertTrue(descriptor.areEqual(firstEntity, secondEntity));
}

@Test
public void testNullPropertyType() {
JsonTypeDescriptor descriptor = new JsonTypeDescriptor();
Expand Down Expand Up @@ -120,4 +153,40 @@ public int hashCode() {
return Objects.hash(formFields);
}
}

private static class FormImpl extends AbstractForm {
private FormImpl(String value) {
super(value);
}
}

private static abstract class AbstractForm {
private String value;

private AbstractForm(String value) {
this.value = value;
}

@Override
public boolean equals(Object o) {
return true;
}

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

private static class FormWithoutEqualsMethod {
private String value;

public String getValue() {
return value;
}

private FormWithoutEqualsMethod(String value) {
this.value = value;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,11 @@ public boolean areEqual(Object one, Object another) {
(one instanceof Map && another instanceof Map)) {
return Objects.equals(one, another);
}
if (one.getClass().equals(another.getClass()) &&
ReflectionUtils.getDeclaredMethodOrNull(one.getClass(), "equals", Object.class) != null) {
return one.equals(another);
if (one.getClass().equals(another.getClass())) {
var equalsMethod = ReflectionUtils.getMethodOrNull(one.getClass(), "equals", Object.class);
if (equalsMethod != null && !Object.class.equals(equalsMethod.getDeclaringClass())) {
return one.equals(another);
}
}
return objectMapperWrapper.toJsonNode(objectMapperWrapper.toString(one)).equals(
objectMapperWrapper.toJsonNode(objectMapperWrapper.toString(another))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,39 @@ public void testSetsAreEqual() {
assertTrue(descriptor.areEqual(theFirst, theSecond));
}

/**
* When the JSON object contains an explicit equals method, even when defined on the abstract super class {@link AbstractForm},
* that equals method should be used.
* If JSON serialization is used,
* the {@link JsonJavaTypeDescriptor#areEqual(Object, Object)} depends on the values of the fields.
*
* The equals method of the {@link FormImpl} always returns true, so the two objects should be equal,
* even when having a different value.
*/
@Test
public void testAbstractClassImplementationsAreEqual() {
JsonJavaTypeDescriptor descriptor = new JsonJavaTypeDescriptor();

FormImpl firstEntity = new FormImpl("value1");
FormImpl secondEntity = new FormImpl("value2");

assertTrue(descriptor.areEqual(firstEntity, secondEntity));
}

/**
* When the JSON object does not contain an explicit equals method, it should not use the equals method {@link Object},
* but should use the ObjectWrapperMapper to equal the objects as JsonNodes
*/
@Test
public void testClassesWithoutEqualsMethodShouldEqualAsJsonNodes() {
JsonJavaTypeDescriptor descriptor = new JsonJavaTypeDescriptor();

FormWithoutEqualsMethod firstEntity = new FormWithoutEqualsMethod("value1");
FormWithoutEqualsMethod secondEntity = new FormWithoutEqualsMethod("value1");

assertTrue(descriptor.areEqual(firstEntity, secondEntity));
}

@Test
public void testNullPropertyType() {
JsonJavaTypeDescriptor descriptor = new JsonJavaTypeDescriptor();
Expand Down Expand Up @@ -120,4 +153,40 @@ public int hashCode() {
return Objects.hash(formFields);
}
}

private static class FormImpl extends AbstractForm {
private FormImpl(String value) {
super(value);
}
}

private static abstract class AbstractForm {
private String value;

private AbstractForm(String value) {
this.value = value;
}

@Override
public boolean equals(Object o) {
return true;
}

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

private static class FormWithoutEqualsMethod {
private String value;

public String getValue() {
return value;
}

private FormWithoutEqualsMethod(String value) {
this.value = value;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,11 @@ public boolean areEqual(Object one, Object another) {
(one instanceof Map && another instanceof Map)) {
return Objects.equals(one, another);
}
if (one.getClass().equals(another.getClass()) &&
ReflectionUtils.getDeclaredMethodOrNull(one.getClass(), "equals", Object.class) != null) {
return one.equals(another);
if (one.getClass().equals(another.getClass())) {
var equalsMethod = ReflectionUtils.getMethodOrNull(one.getClass(), "equals", Object.class);
if (equalsMethod != null && !Object.class.equals(equalsMethod.getDeclaringClass())) {
return one.equals(another);
}
}
return objectMapperWrapper.toJsonNode(objectMapperWrapper.toString(one)).equals(
objectMapperWrapper.toJsonNode(objectMapperWrapper.toString(another))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,39 @@ public void testSetsAreEqual() {
assertTrue(descriptor.areEqual(theFirst, theSecond));
}

/**
* When the JSON object contains an explicit equals method, even when defined on the abstract super class {@link AbstractForm},
* that equals method should be used.
* If JSON serialization is used,
* the {@link JsonJavaTypeDescriptor#areEqual(Object, Object)} depends on the values of the fields.
*
* The equals method of the {@link FormImpl} always returns true, so the two objects should be equal,
* even when having a different value.
*/
@Test
public void testAbstractClassImplementationsAreEqual() {
JsonJavaTypeDescriptor descriptor = new JsonJavaTypeDescriptor();

FormImpl firstEntity = new FormImpl("value1");
FormImpl secondEntity = new FormImpl("value2");

assertTrue(descriptor.areEqual(firstEntity, secondEntity));
}

/**
* When the JSON object does not contain an explicit equals method, it should not use the equals method {@link Object},
* but should use the ObjectWrapperMapper to equal the objects as JsonNodes
*/
@Test
public void testClassesWithoutEqualsMethodShouldEqualAsJsonNodes() {
JsonJavaTypeDescriptor descriptor = new JsonJavaTypeDescriptor();

FormWithoutEqualsMethod firstEntity = new FormWithoutEqualsMethod("value1");
FormWithoutEqualsMethod secondEntity = new FormWithoutEqualsMethod("value1");

assertTrue(descriptor.areEqual(firstEntity, secondEntity));
}

@Test
public void testNullPropertyType() {
JsonJavaTypeDescriptor descriptor = new JsonJavaTypeDescriptor();
Expand Down Expand Up @@ -120,4 +153,40 @@ public int hashCode() {
return Objects.hash(formFields);
}
}

private static class FormImpl extends AbstractForm {
private FormImpl(String value) {
super(value);
}
}

private static abstract class AbstractForm {
private String value;

private AbstractForm(String value) {
this.value = value;
}

@Override
public boolean equals(Object o) {
return true;
}

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

private static class FormWithoutEqualsMethod {
private String value;

public String getValue() {
return value;
}

private FormWithoutEqualsMethod(String value) {
this.value = value;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,11 @@ public boolean areEqual(Object one, Object another) {
(one instanceof Map && another instanceof Map)) {
return Objects.equals(one, another);
}
if (one.getClass().equals(another.getClass()) &&
ReflectionUtils.getDeclaredMethodOrNull(one.getClass(), "equals", Object.class) != null) {
return one.equals(another);
if (one.getClass().equals(another.getClass())) {
var equalsMethod = ReflectionUtils.getMethodOrNull(one.getClass(), "equals", Object.class);
if (equalsMethod != null && !Object.class.equals(equalsMethod.getDeclaringClass())) {
return one.equals(another);
}
}
return objectMapperWrapper.toJsonNode(objectMapperWrapper.toString(one)).equals(
objectMapperWrapper.toJsonNode(objectMapperWrapper.toString(another))
Expand Down
Loading

0 comments on commit 0a98c3f

Please sign in to comment.