The recommendation is to use a surrogate key (i.e. BuildingId) with no business meaning as a primary key. This makes sense for a number of reasons. The business key, Name, should be a separate column with its own semantics (unique constraint, not-null, etc.). You would use this key to implement hashcode( ) and equals( ) to create the appropriate behavior in Sets.
For legacy systems it is possible to specify a business key as a primary key, but you run into several problems. First, an ORM tool has no way of knowing what the old key is, so updates are impossible. If you changed the name from "Bldg 305" to "Blg 306" then Hibernate can't say "Update building set name='306' where name='305'" because the 305 is lost. Because it's the primary key, the only way to retain it would be to save a copy somewhere, necessitating a tighter coupling, etc. You could, I suppose, update the name where all of the other fields are the same, but there's nothing to say the other fields couldn't have changed as well. There's no simple, efficient, or reliable way to change a primary key.
The other problem is associations and inverse relationships. I haven't thought through the gamut of complications that a changeable primary key would cause with those, but I imagine it's quite a mess.
What you could do, I suppose, is delete( ) the object, change the key, and then save( ) the object, which might, depending on your associations and cascade settings, re-persist your entire object graph in the database. It's also kind of risky, since you are in essence deleting things and re-inserting them.
- Jesse
|