开发者

What is the best practice when implementing equals() for entities with generated ids

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:

  1. define equality based on A
  2. define equality based on B and C

or, it wouldn't really matter which of the two I choose.


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.


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.


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)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜