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

Return value of equals changing along the way #309

Closed
lombokissues opened this issue Jul 14, 2015 · 9 comments
Closed

Return value of equals changing along the way #309

lombokissues opened this issue Jul 14, 2015 · 9 comments
Labels

Comments

@lombokissues
Copy link

Migrated from Google Code (issue 236)

@lombokissues
Copy link
Author

👤 dsuepke   🕗 Jul 14, 2011 at 16:09 UTC

What is the expected output? What do you see instead?
super.equals(obj) returns true, but it's changed to false when being delivered by Lombok.

What version of the product are you using? On what operating system?
Linux/Eclipse helios/Lombok 0.10.0-RC1

Please provide any additional information below.

//@ EqualsAndHashCode(callSuper=true, exclude="someAttr")
public @ Data class SomeEntity extends ParentEntity {
...
@ Override
public boolean equals(Object obj) {
return super.equals(obj);
}
}

This will return true. If I remove the equals method in SomeEntity and uncomment @ EqualsAnd... again, it is calling super.equals as it should (checked in debugger), but along the way the return value is somehow changed from true to false. This makes using @ Data pretty much useless, as I need to get the correct equals value. Would be thankful for any help

@lombokissues
Copy link
Author

👤 dsuepke   🕗 Jul 14, 2011 at 16:10 UTC

Sorry, it's not eclipse helios but eclipse indigo

@lombokissues
Copy link
Author

👤 pe.fips   🕗 Jul 14, 2011 at 21:35 UTC

Lomboks @ EqualsAndHashCode creates an instanceof check (see: https://projectlombok.org/features/EqualsAndHashCode.html) that will most likely fail in your example, that's why you observe a misbehavior, that actually is none.

Please try this simplified equals implementation, it should fail as well.

@ Override
public boolean equals(Object obj) {
if (!(obj instanceof SomeEntity)) return false;
return super.equals(obj);
}

If this doesn't help let me know, but I'm pretty sure @ EAHC works fine.

@lombokissues
Copy link
Author

👤 pe.fips   🕗 Jul 14, 2011 at 21:43 UTC

Long story short, I assume that lombok generates an equals method you did not expect.
But maybe I'm assuming wrong. Make sure to check the feature example. If you need another implementation you can't use @ EAHC, but be advised that lombok pretty much offers the text-book implementation of equals.

@lombokissues
Copy link
Author

👤 dsuepke   🕗 Jul 15, 2011 at 07:09 UTC

Many thanks for your replies. I tried the example and it's not failing, working just fine. In fact, super.equals is actually implemented as
@ Override
public boolean equals(Object obj) {
if (obj instanceof ParentEntity) {
return this.getID() == ((ParentEntity)obj).getID();
}
return super.equals(obj);
}

So there already is an instanceof-check (though not on the object class itself but its parent, but that's just working fine). So it's not that or I'm missing a point. Also, should Lombok create an equals-method at all (even if it's only an instance-check), if "callSuper=true" is defined?

If I find the time (can't promise), I'll try to create a minimum working example on the weekend.

@lombokissues
Copy link
Author

👤 pe.fips   🕗 Jul 15, 2011 at 07:50 UTC

I think I finally understand want you are trying to achieve.
You are using @ Data on your subclass but you don't want an equals() method at all or, if need be, an equals() method that just calls super.equals().

I'm afraid thats not the intention of @ EqualsAndHashCode.

As a solution you could:

[A] Override equals() yourself, as you did in your initial report

or

[B] Replace @ Data with @ RequiredArgsConstructor @ Getter @ Setter since @ Data is shorthand for @ RequiredArgsConstructor, @ Getter, @ Setter and @ EqualsAndHashCode

And if I'm still on the wrong track a small example would be really appreciated.

@lombokissues
Copy link
Author

👤 r.spilker   🕗 Jul 18, 2011 at 19:28 UTC

We just added a fix (see issue #313) that overriding just 1 of these methods will cause the others to not be generated. So, starting at version 0.10.0-RC2, you can use @ Data and add:

@ Override public boolean equals(Object other) {
return super.equals(other);
}

and all will be well. However, I doubt that's the equals method you want to write, as it will lead to a number of problems, depending on the equals impl of parent (for example, child.equals(parent) might be true, but if thats true, is parent.equals(child) also true? It should be, otherwise you broke the equals contract). Lombok generates a canEqual construct just for such an occasion.

@lombokissues
Copy link
Author

👤 dsuepke   🕗 Jul 19, 2011 at 07:05 UTC

Thanks for you remarks, that was helpful. I will just include the equals method to stop @ Data from adding further checks. Intuitively I'd say that if I say "callSuper=true" there should be no need to provide the method, but that's certainly not a big deal.

The equals contract should be mutually true, as both instances will always be of the type ParentEntity, thus the id check should work.

Thanks again

@lombokissues
Copy link
Author

End of migration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant