I just ran into a rather nasty bug/gotcha with comparing Dates using the equals comparison that frankly shocked me. As an example, you can reproduce with the following test, running against the standard test dataset. (I was running against Core 2.5.x)
Encounter encounter = Context.getEncounterService().getEncounter(3); Date encounterDate = new Date(encounter.getEncounterDatetime().getTime()); Assert.assertTrue(encounterDate.equals(encounter.getEncounterDatetime())); // PASSES Assert.assertTrue(encounter.getEncounterDatetime().equals(encounterDate)); // FAILS
Note that the first assertion passes, and the second doesn’t.
What’s happening here is that when Hibernate hydrates the encounter date, it’s getting hydrated as a Timestamp, but the encounterDate I create in the second line is a pure Date… and evidently Timestamp equals is not symmetric with the base Date equal:
The bottom line is simply to not use equals, but to use something like Apache DateUtils.isSameInstant to compare dates or a handy OpenMRS Util method for doing this: openmrs-core/OpenmrsUtil.java at master · openmrs/openmrs-core · GitHub
So the fix is easy, but I would think there are numerous places in the code where were are using the equals method and expecting it to work… but maybe it’s just me and everybody knew about this… .
I’m also wondering why Hibernate instantiates encounterDatetime as a Timestamp instead of a Date.
fyi @mseaton @dkayiwa @mksd @burke @ibacher
Take care, Mark