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

Request to Change Functionality of Models equals() Method #23

Closed
tzyang opened this issue Aug 24, 2022 · 1 comment
Closed

Request to Change Functionality of Models equals() Method #23

tzyang opened this issue Aug 24, 2022 · 1 comment
Assignees
Labels
bug Something isn't working

Comments

@tzyang
Copy link

tzyang commented Aug 24, 2022

Currently for all model classes which extends DefectDojoModel the equals method will not return true even when two models have the exact same field values. The only time equals will return true it calls it on itself.

For example, using the model User:

//Create two Users using the no args constructors, all fields for the created users will be null.
User user1 = new User();
User user2 = new User();

//This will be false even though all fields match.
System.out.println(user.equals(user2));

//Create two Users using the all args constructor, with the same fields.
User userFullArgs1 = new User(1l, "username", "firstname", "lastname");
User userFullArgs2 = new User(1l, "username", "firstname", "lastname");

//This will be false even though all fields match.
System.out.println(userFullArgs1.equals(userFullArgs2)); 

//The following two lines will be true.
System.out.println(user1.equals(user1));
System.out.println(userFullArgs2.equals(useFullArgs2));

With the current implementation of the models the equals method will never return true unless it calls it on itself.

The reason behind this behavior is due to the @EqualsAndHashCode(callSuper = true) annotation within the models. The callSuper = true flag introduces logic into the equals method that calls super.equals() the super would be the parent class DefectDojoModel. Since DefectDojoModel does not have an equals() method it inherits the Object.equals() implementation. Object.equals() will only return true if the object references are the same, regardless of any field values. Hence the behavior above.

Some more detailed information on the annotation here: https://projectlombok.org/features/EqualsAndHashCode

A proposed change would be to make it so that the equals method would return true in the case that all fields are matching. This can be accomplished by changing the @EqualsAndHashCode(callSuper = true) annotation from true to false, or removing the parenthesis portion, or removing that annotation entirely. All three suggestions should ultimately have the same effect.

@Weltraumschaf Weltraumschaf added the bug Something isn't working label Jul 20, 2023
@Weltraumschaf Weltraumschaf self-assigned this Jul 20, 2023
@Weltraumschaf Weltraumschaf moved this from Backlog to Todo in secureCodeBox v4 Jul 20, 2023
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jul 20, 2023
…nttion

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jul 21, 2023
…nttion

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jul 21, 2023
…nttion

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jul 21, 2023
…nttion

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jul 21, 2023
…nttion

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jul 24, 2023
…nttion

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Zero3141 pushed a commit that referenced this issue Jul 24, 2023
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
@Weltraumschaf Weltraumschaf moved this from Todo to In Progress in secureCodeBox v4 Jan 26, 2024
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jan 26, 2024
…tract

Problem of equals and inheritance:
As described in this[1] blog post the Object#equals() requires that it
fulfills the Liskov Substitution Principle (LSP). Our implemenation
breaks this contract. Even worse, it didn't work at all as descibed
in issue 23[2].

Since the BaseModel class does not have any properties, we can remove it.

This patch removes this obsolete class. Also it makes all model classes
final and all properties private. This is an implicit requirement of the
contract of hashCode() to avoid memory leaks in collections. (See linked
blog post on Artima for more details.)

Actually objects must be immutable -- all fields final -- to guaruantee
a stable equal/hashCode behaviour for the whole lifetime of the objects.
But this must be further investigated, if this is possible. For now we
ignore this warning in the test code.

1: https://www.artima.com/articles/how-to-write-an-equality-method-in-java
2: secureCodeBox#23

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jan 26, 2024
Native types should be favored over boxed types for two reasons:

1. Boxed types introduce more verbose code.
2. Boxed types introduce possible NPE.

Since native types reduces code clutter because they have a default value
and they also can not be null, we switched to native type fields.

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jan 26, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jan 26, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jan 26, 2024
Also add missing null check in implementation.

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jan 26, 2024
…memtations

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jan 26, 2024
Since the implementation of isNameEqual returns false, if the
value in the map is null, we do this for id the same way to be
consistent.

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jan 26, 2024
Native types should be favored over boxed types for two reasons:

1. Boxed types introduce more verbose code.
2. Boxed types introduce possible NPE.

Since native types reduces code clutter because they have a default value
and they also can not be null, we switched to native type fields.

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jan 26, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jan 26, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jan 26, 2024
Also add missing null check in implementation.

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jan 26, 2024
…memtations

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Jan 26, 2024
Since the implementation of isNameEqual returns false, if the
value in the map is null, we do this for id the same way to be
consistent.

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Feb 2, 2024
…tract

Problem of equals and inheritance:
As described in this[1] blog post the Object#equals() requires that it
fulfills the Liskov Substitution Principle (LSP). Our implemenation
breaks this contract. Even worse, it didn't work at all as descibed
in issue 23[2].

Since the BaseModel class does not have any properties, we can remove it.

This patch removes this obsolete class. Also it makes all model classes
final and all properties private. This is an implicit requirement of the
contract of hashCode() to avoid memory leaks in collections. (See linked
blog post on Artima for more details.)

Actually objects must be immutable -- all fields final -- to guaruantee
a stable equal/hashCode behaviour for the whole lifetime of the objects.
But this must be further investigated, if this is possible. For now we
ignore this warning in the test code.

1: https://www.artima.com/articles/how-to-write-an-equality-method-in-java
2: secureCodeBox#23

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Feb 2, 2024
Native types should be favored over boxed types for two reasons:

1. Boxed types introduce more verbose code.
2. Boxed types introduce possible NPE.

Since native types reduces code clutter because they have a default value
and they also can not be null, we switched to native type fields.

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Feb 5, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Feb 5, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Feb 5, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Feb 5, 2024
…ic API

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Feb 6, 2024
…ns Have

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Feb 6, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Problem of equals and inheritance:
As described in this[1] blog post the Object#equals() requires that it
fulfills the Liskov Substitution Principle (LSP). Our implemenation
breaks this contract. Even worse, it didn't work at all as descibed
in issue 23[2].

Since the BaseModel class does not have any properties, we can remove it.

This patch removes this obsolete class. Also it makes all model classes
final and all properties private. This is an implicit requirement of the
contract of hashCode() to avoid memory leaks in collections. (See linked
blog post on Artima for more details.)

Actually objects must be immutable -- all fields final -- to guaruantee
a stable equal/hashCode behaviour for the whole lifetime of the objects.
But this must be further investigated, if this is possible. For now we
ignore this warning in the test code.

1: https://www.artima.com/articles/how-to-write-an-equality-method-in-java
2: #23

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Native types should be favored over boxed types for two reasons:

1. Boxed types introduce more verbose code.
2. Boxed types introduce possible NPE.

Since native types reduces code clutter because they have a default value
and they also can not be null, we switched to native type fields.

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Also add missing null check in implementation.

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Since the implementation of isNameEqual returns false, if the
value in the map is null, we do this for id the same way to be
consistent.

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
This is necessary to avoid that something else than types
implementing Model can be wrapped because the service already
require this by upper bounds.

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
- Simplify by removing unnecessary setup method.
- Use distinct values in fixture to make it easier spotting bugs.

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit that referenced this issue Feb 9, 2024
Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
@Weltraumschaf
Copy link
Member

Fixed.

@github-project-automation github-project-automation bot moved this from In Progress to Done in secureCodeBox v4 Feb 9, 2024
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Aug 30, 2024
This reverts commit 49ca35d.

DefectDojo does not expect id properties in POST request, but instead
of ignoring them it is required toset them to null.

This is only possible with boxed types.

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Weltraumschaf added a commit to Weltraumschaf/defectdojo-client-java that referenced this issue Sep 2, 2024
This reverts commit 49ca35d.

DefectDojo does not expect id properties in POST request, but instead
of ignoring them it is required toset them to null.

This is only possible with boxed types.

Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Archived in project
Development

No branches or pull requests

2 participants