-
Notifications
You must be signed in to change notification settings - Fork 89
fix: update equals & hashCode of model classes to satisfy the expected contract #1446
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
Conversation
03cd7c0 to
436abb6
Compare
…d contract According to the official Javadocs, there is a contract that must exist between #equals(Object)[1] and #hashCode()[2] for every class. Prior to this change the contract was not upheld for the model classes due to multiple reasons: 1. Some classes did not define equals or hashCode instead relying on the default implementations from java.lang.Object 2. Some classes were using different sets of fields between the two methods 3. Some classes were not performing deep evaluation 4. Some classes were serializing themselves to the apiary models before calling equals on the serialized instances All model classes have been updated to ensure: 1. They define an equals and hashCode 2. The contract is upheld for these methods Additionally, all internal usage of the deprecated DeleteRule has been removed from BlobInfo. Instead, LifecycleRule are used exclusively. Deprecated getDeleteRule and setDeleteRule have had their implementations changed to perform an immediate conversion to/from LifecycleRule as necessary. ApiaryConversions has been updated to ignore DeleteRule when encoding & decoding. A codec for converting between DeleteRule <-> LifecycleRule has been added to BackwardCompatibilityUtils. Corresponding tests for conversions between the various types of DeleteRules have been added in BackwardCompatibilityUtilsTest. Utils.ifNonNull has been updated to test the return value of the mapping function before consuming it. Data.<Boolean>nullOf(Boolean.class) returns `true` which can lead to unexpected behavior if a null value is provided to it indirectly. New Codec#andThen(Codec) has been added to allow easily connecting two Codecs. [1] https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object- [2] https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--
436abb6 to
88016b9
Compare
frankyn
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall LGTM, thanks for simplifying the story for deleteRules and lifecycleRules to have a single source
| return Objects.equals( | ||
| Conversions.apiary().bucketInfo().encode(this), | ||
| Conversions.apiary().bucketInfo().encode(that)); | ||
| return Objects.equals(generatedId, that.generatedId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a test that can be added to check if all metadata values are set? This can be easily missed again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like in general this is more of a "java best practice" to regenerate equals and hashcode when you add a property.
We may want to look into replacing the direct models with something generated in the future, which would automatically include all of the properties.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you be open to Autoclass?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly, we'd have to investigate if it supported all the odd translations and hierarchies we need to support from a binary & source compatibility standpoint
According to the official Javadocs, there is a contract that must exist between
#equals(Object)[1] and #hashCode()[2] for every class.
Prior to this change the contract was not upheld for the model classes due to
multiple reasons:
implementations from java.lang.Object
equals on the serialized instances
All model classes have been updated to ensure:
Additionally, all internal usage of the deprecated DeleteRule has been removed
from BlobInfo. Instead, LifecycleRule are used exclusively. Deprecated
getDeleteRule and setDeleteRule have had their implementations changed to
perform an immediate conversion to/from LifecycleRule as necessary.
ApiaryConversions has been updated to ignore DeleteRule when encoding & decoding.
A codec for converting between DeleteRule <-> LifecycleRule has been added to
BackwardCompatibilityUtils. Corresponding tests for conversions between the
various types of DeleteRules have been added in BackwardCompatibilityUtilsTest.
Utils.ifNonNull has been updated to test the return value of the mapping
function before consuming it. Data.nullOf(Boolean.class) returns
truewhich can lead to unexpected behavior if a null value is provided to it
indirectly.
New Codec#andThen(Codec) has been added to allow easily connecting two Codecs.
[1] https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-
[2] https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode--