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

fix: equals and hashcode of several classes #1364

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

chrfwow
Copy link
Contributor

@chrfwow chrfwow commented Mar 6, 2025

This PR

Fixes some of the equals and hashcode methods in the sdk.

Related Issues

Fixes #1362

Notes

I assumed that for the classes I modified, two objects should be equal iff their underlying data is equal. E.g. the class Value. Two distinct Value objects should be equal if they represent the same data:

        Value val1 = new Value(12312312);
        Value val2 = new Value(12312312);
        assertEquals(val1, val2);

Please comment if you think there are more such cases in the sdk, or if I added this behavior somewhere it is not appropriate.

Signed-off-by: christian.lutnik <christian.lutnik@dynatrace.com>
@chrfwow chrfwow requested a review from a team as a code owner March 6, 2025 14:14
Signed-off-by: christian.lutnik <christian.lutnik@dynatrace.com>
Copy link

sonarqubecloud bot commented Mar 6, 2025

@@ -46,4 +46,46 @@ public Map<String, Object> asObjectMap() {
(accumulated, entry) -> accumulated.put(entry.getKey(), convertValue(entry.getValue())),
HashMap::putAll);
}

public boolean equals(final Object o) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why implement it instead of adding EqualsAndHashCode and adding inheritors with EqualsAndHashCode**(callSuper = true)** ?
Then it seems to call it on attributes map entries.
similar for others.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lombok's implementation has a bit more overhead, and as we can see from the issue, it is not always an implementation one would expect

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read the issue. By solution of this, it may be suggested that Lombok's implementation is not useful here?
If their implementation works, widely used, and makes the methods redunadant, why not use it?
One thing I see misleading is that callSuper value ia false. But if you add the value as true, isn't it enough to make all the tests pass without explicit implementations?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @liran2000 here, if we can configure lombok to work "as expected" then there is less code to maintain :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Do we want different inheritors of AbstractStructure and classes that delegate to it to equal each other if they have the same underlying AbstractStructure?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think they should be equal, else what's the point of the different classes?

* @param o the other object
* @return true iff both objects are equal or represent the same data
*/
public boolean equals(final Object o) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too, similar implementation to the EqualsAndHashCode by delombok.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want a Value object to have the same hashCode as its innerObject?

Copy link

@glissand0 glissand0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing the issue so promptly, appreciate it! 👍


@Test
void unequalMutableStructuresAreNotEqual() {
MutableStructure m1 = new MutableStructure();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor comment: the MutableStructure tests are in ImmutableStructureTest. Should they be moved into a separate class?

@@ -46,4 +46,46 @@ public Map<String, Object> asObjectMap() {
(accumulated, entry) -> accumulated.put(entry.getKey(), convertValue(entry.getValue())),
HashMap::putAll);
}

public boolean equals(final Object o) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @liran2000 here, if we can configure lombok to work "as expected" then there is less code to maintain :)

@glissand0
Copy link

Perhaps in a separate PR could we address the toString generation as well? Eg, for MutableStructure it is

public String toString() {return "MutableStructure()";}

@tostring(callSuper = true) generates what we want

@chrfwow chrfwow self-assigned this Mar 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MutableContext / MutableStructure equality bug
3 participants