Reputation: 163
If I have a table with columns A, B, C, D
A: auto-generated id (PK)
B & C: combination must be unique (these are the columns that actually define identity in the business sense)
D: some other columns
Now, if I'll create business objects based on this table (e.g. in Java), which one would be a better implementation of the equals() method:
or, it wouldn't really matter which of the two I choose.
Upvotes: 12
Views: 5951
Reputation: 27235
I agree with @S.P.Floyd as well. But I wanted to add something more.
There are situations when an entity doesn't have unique business properties. For instance, an entity may only have A
(the PK) and B
(a business property), but many entities have the same B
value.
In this case, it is difficult to create an equals()
and hashcode()
. You certainly do not want to base them on A
, as you won't be able to compare a persisted object with one that hasn't been persisted yet. And you can't base it on B
alone, because then many objects that are different unique entities would appear to be the same.
What I do in these situations is have a Date created = new Date();
property. When an entity is created, it automatically gets a created timestamp. In my equals()
and hashcode()
I include both B
and created
. This isn't perfect, as there is a very slim chance that two objects could be created at the same time (especially in a clustered solution), but it's a start. If you must, add a UID or other generated business property that isn't the database's PK.
Upvotes: 3
Reputation: 114807
If (B,C) is a unique pair, there's no need for an auto-generated id in addition. For the table, A is equivalent to (B,C) (one-to-one relation).
You may want or need the extra key, but I agree with seanizer, use (B,C) for equals and because A is redundant (and null
before the object is persisted), don't use that for equals (and hashcode)
Upvotes: 2
Reputation: 299048
Definitely B and C, because you want the equals()
contract to be valid even before entities are persisted. You say yourself:
these are the columns that actually define identity in the business sense
If that is the case, then that is the logic equals()
should use. Database keys are the database's concern and should be of no concern to your business layer.
And don't forget to use the same properties in hashcode()
, too.
Upvotes: 21