views:

511

answers:

5

Short version:

Is there a simple way to get the value of a primary key after doing a merge() in Hibernate JPA?

Details:

I'm making a generic library that uses Hibernate. The library uses JPA's merge() to serialize a POJO to the database. What's the best way to discover the primary key's new value? I'm assuming that the primary key will never be a composite key. However, there are cases where the POJO is a subclass of class containing the primary key. So, using reflection on the POJO isn't an easy answer (ie it's necessary to reflect the class and all super classes).

Any suggestions?

A: 

Merge assumes that you already have persistent instance, it should not modify you PK

DroidIn.net
A: 

We have an application where every entity has a primary key of type Long. We then force all of the Entity classes to implement an interface Idable which contains a single method:

Long getId();

For any generic code that requires the ID, we can then cast to Idable and call getId() to retrieve the primary key.

If your classes might contain different types, you could make the getId() method return Object which JDK5's Covariant Return Types feature will allow you to still use normally (even if the class declares the method to return a different type such as Long). In this case, if the class' primary key is not called "id" you will need to tag the method implementation as @Transient so that Hibernate/JPA doesn't pick it up as a separate property.

Adam Batkin
A: 

You can look at all of the methods (or fields) in the class (and parent classes) until you find one with the @Id tag, then use that field to get the value off of the returned result from the merge call.

Outside of that, I do not know of a way without knowing what the element is directly.

Edit Much like someone else mentioned, you could require a standard method - and this could be on an interface. Thus, you could cast the classes to that interface, and then get the id off of them.

aperkins
A: 

All of my persistent classes inherit from PersistentObject, which provides the id, and version fields. Other the providing a getter method, there really is no other way of getting the ID.

Jim Barrows
A: 

The Hibernate SessionFactory has methods to do this: SessionFactory.getClassMetaData().getIdentifierPropertyName(). From there I was able to get it working.

Thanks everyone!

User1