Don't Let Hibernate Steal Your Identity
Subject:   What about this?
Date:   2007-01-19 13:28:14
From:   monocongo
Thanks for this well written article.

Someone I work with has brought up what seems to be a reasonable objection to using this approach.

As an example I'll use a simple mapped object called Product, which maps to a primary key column productId and a price column. The UUID approach of the article is also incorporated into the Product class so there's a UUID field as well which is not mapped to a column of the database table.

Let's say we have a Product object product1 which is persistent with its productId == "ABC123", and it has a UUID == "123-abc-456". Then we create a new Product object product2 and set the productId = "ABC123", but product2 is not yet persisted or even loaded into the Hibernate Session. The UUID field of product2 will be unique from the UUID of product1, but from an ORM standpoint the two objects should reference the same row in the database by virtue of the fact that their productId fields (which are equal) identify the same row in the Product table. However if we use the equals() approach outlined in this article then the two objects are not considered equal since they're actually different objects with different UUID fields. The two Product objects are different, and hence not equal based on the UUID comparison, but the row in the database that they reference via their productId fields is the same, so in a sense the two objects really are equal.

For example this test will fail:

public void testEquals() {

Product product1 = productDao.findById("ABC123");
Product product2 = new Product();

assertTrue("The two Products are not equal", product1.equals(product2));

This seems to be a good reason for using an equals() which compares the natural key (productId in this example). Is this a valid conclusion, or am I missing something here?