Skip to content

Fix Comparable Contract Violation in SharedBibEntryData (#15806)#15842

Merged
calixtus merged 3 commits into
JabRef:mainfrom
MateusLyoshka:fix-for-issue-15806
May 27, 2026
Merged

Fix Comparable Contract Violation in SharedBibEntryData (#15806)#15842
calixtus merged 3 commits into
JabRef:mainfrom
MateusLyoshka:fix-for-issue-15806

Conversation

@MateusLyoshka

@MateusLyoshka MateusLyoshka commented May 27, 2026

Copy link
Copy Markdown
Contributor

#15806 Fix Comparable contract violation in SharedBibEntryData

Closes #15806

SharedBibEntryData implements Comparable<SharedBibEntryData> but was missing equals and hashCode implementations, violating the contract that compareTo returning 0 must be consistent with equals. Both methods were added along with tests covering their consistency.

    `jabref-contrib-policy:4.2:reviewed​:ok`

Run SharedBibEntryDataTest — all 4 tests should pass. Alternatively, verify manually that two default SharedBibEntryData instances are equal and have the same hash code.
Note: SharedBibEntryData is only active in shared SQL database mode. Manual testing in a live shared database setup is impractical for this fix. The behavior is fully covered by the added JUnit tests.

Claude Code (model claude-sonnet-4-6)

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • If AI tools were used, I disclosed them in the "AI usage" section and reviewed, understood, and take full ownership of all AI-generated code
  • I manually tested my changes in running JabRef (always required)
  • I added JUnit tests for changes (if applicable)
  • [/] I added screenshots in the PR description (if change is visible to the user)
  • [/] I added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • [/] I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • [/] I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

* Add an override to equals and hashCode function to satisfy Comparable contract.

* Add SharedBibEntryDataTest covering equals/hashCode/compareTo consistency.
Copilot AI review requested due to automatic review settings May 27, 2026 20:05
@github-actions

Copy link
Copy Markdown
Contributor

Hey @MateusLyoshka! 👋

Thank you for contributing to JabRef!

We have automated checks in place, based on which you will soon get feedback if any of them are failing. We also use Qodo for review assistance. It will update your pull request description with a review help and offer suggestions to improve the pull request.

After all automated checks pass, a maintainer will also review your contribution. Once that happens, you can go through their comments in the "Files changed" tab and act on them, or reply to the conversation if you have further inputs. You can read about the whole pull request process in our contribution guide.

Please ensure that your pull request is in line with our AI Usage Policy and make necessary disclosures.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Fix Comparable contract violation in SharedBibEntryData

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Implements equals() and hashCode() methods in SharedBibEntryData
• Ensures consistency with existing compareTo() implementation
• Adds comprehensive JUnit tests for contract compliance
Diagram
flowchart LR
  A["SharedBibEntryData<br/>implements Comparable"] -->|missing| B["equals() and hashCode()"]
  B -->|violates| C["Comparable contract"]
  D["Add equals() method"] -->|compares| E["sharedID and version"]
  F["Add hashCode() method"] -->|hashes| E
  D -->|ensures| G["Contract compliance"]
  F -->|ensures| G
  H["Add unit tests"] -->|validates| G

Loading

Grey Divider

File Changes

1. jablib/src/main/java/org/jabref/model/entry/SharedBibEntryData.java 🐞 Bug fix +18/-0

Add equals and hashCode implementations

• Added Objects import for hash computation
• Implemented equals() method comparing sharedID and version fields
• Implemented hashCode() method using Objects.hash() on both fields
• Ensures consistency with existing compareTo() implementation

jablib/src/main/java/org/jabref/model/entry/SharedBibEntryData.java


2. jablib/src/test/java/org/jabref/model/entry/SharedBibEntryDataTest.java 🧪 Tests +44/-0

Add comprehensive tests for equals and hashCode

• Created new test class with four test methods
• Tests that equals() returns true when compareTo() returns zero
• Tests that equals() returns false when sharedID differs
• Tests that equals() returns false when version differs
• Tests that equal objects have identical hash codes

jablib/src/test/java/org/jabref/model/entry/SharedBibEntryDataTest.java


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)

Context used

Grey Divider


Remediation recommended

1. Mutable equals/hashCode keys 🐞 Bug ☼ Reliability
Description
SharedBibEntryData.equals/hashCode now depend on sharedID/version, but these fields are mutable and
are actively changed during DB sync. If a SharedBibEntryData instance (or an object containing it)
is ever inserted into a HashMap/HashSet and then setSharedID/setVersion is called, lookups/removals
may fail because the hash bucket changes.
Code

jablib/src/main/java/org/jabref/model/entry/SharedBibEntryData.java[R49-63]

Evidence
The new equals/hashCode use the mutable fields sharedID and version, and those same fields are
publicly mutable via setters and are mutated during normal shared-DB operation (ID assignment and
version synchronization). This creates the standard Java hazard where an object’s hashCode changes
after being placed into a hash-based collection.

jablib/src/main/java/org/jabref/model/entry/SharedBibEntryData.java[14-39]
jablib/src/main/java/org/jabref/model/entry/SharedBibEntryData.java[49-63]
jablib/src/main/java/org/jabref/logic/shared/DBMSProcessor.java[175-178]
jablib/src/main/java/org/jabref/logic/shared/DBMSSynchronizer.java[175-187]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`SharedBibEntryData` now implements value-based `equals`/`hashCode` using `sharedID` and `version`, but those fields are mutable and are changed after object creation (e.g., when IDs are assigned or versions are synced). Objects with mutable `hashCode`/`equals` fields are unsafe to use in hash-based collections because mutation after insertion can make the object unreachable.

### Issue Context
This PR fixes the `Comparable`/`equals` consistency issue, but it introduces/solidifies a new footgun: the class is still mutable while now having value-based equality.

### Fix Focus Areas
Choose one of these directions:
- Make `SharedBibEntryData` immutable (remove setters; update call sites to replace instances when values change), or
- Restrict mutation semantics (e.g., setters package-private + ensure objects are never used as hash keys), and/or
- Add explicit Javadoc warnings/tests to prevent future misuse in hash-based collections.

- jablib/src/main/java/org/jabref/model/entry/SharedBibEntryData.java[49-63]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds value-based equality semantics to SharedBibEntryData and validates them with unit tests.

Changes:

  • Implemented equals and hashCode in SharedBibEntryData based on sharedID and version
  • Added JUnit tests covering equality/inequality and hash code behavior

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
jablib/src/main/java/org/jabref/model/entry/SharedBibEntryData.java Adds equals/hashCode implementations to support value-based comparisons
jablib/src/test/java/org/jabref/model/entry/SharedBibEntryDataTest.java Introduces unit tests for the new equality and hashing behavior

@github-actions github-actions Bot added the status: changes-required Pull requests that are not yet complete label May 27, 2026
@github-actions github-actions Bot added status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete labels May 27, 2026
@github-actions github-actions Bot mentioned this pull request May 27, 2026
2 tasks
@calixtus calixtus added this pull request to the merge queue May 27, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label May 27, 2026
Merged via the queue into JabRef:main with commit fceb24a May 27, 2026
102 of 109 checks passed
Siedlerchr added a commit to InAnYan/jabref that referenced this pull request May 28, 2026
* upstream/main: (29 commits)
  Chore(deps): Bump dev.langchain4j:langchain4j-bom in /versions (JabRef#15853)
  Chore(deps): Bump org.glassfish.jaxb:jaxb-runtime in /versions (JabRef#15854)
  Chore(deps): Bump com.gradleup.shadow:shadow-gradle-plugin (JabRef#15852)
  Chore(deps): Bump com.gradleup.shadow:shadow-gradle-plugin (JabRef#15849)
  Chore(deps): Bump com.autonomousapps:dependency-analysis-gradle-plugin (JabRef#15850)
  Update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.6 (JabRef#15844)
  Fix reset and import of AiPreferences (JabRef#15843)
  Fix Comparable Contract Violation in SharedBibEntryData (JabRef#15806) (JabRef#15842)
  Chore(deps): Bump com.dlsc.gemsfx:gemsfx from 4.0.5 to 4.1.0 in /versions (JabRef#15841)
  Chore(deps): Bump jablib/src/main/resources/csl-styles (JabRef#15840)
  New Crowdin updates (JabRef#15839)
  Add group pseudonymization support (fixes JabRef#14117) (JabRef#15258)
  Feature parse MeSH terms in PubMed MEDLINE records (JabRef#15529)
  Fix/non latin author parsed as name prefix (JabRef#15823)
  Fix not on fx thread cleanup (JabRef#15835)
  Fix garbled BibEntry Javadoc example (JabRef#15834)
  Revert "Fix cleanup operationn setFiles not on fx thread causes exceptiosn"
  Revert "changelog"
  changelog
  Fix cleanup operationn setFiles not on fx thread causes exceptiosn
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

first contrib status: no-bot-comments status: to-be-merged PRs which are accepted and should go into the merge-queue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Comparable Contract Violation

4 participants