views:

398

answers:

1

I have a JPA entity instance in the web UI layer of my application. I'd like to know at anytime if this entity has been already persisted in database or if it is only present in the user session.

It would be in the business layer, I would use entitymanager.contains(Entity) method, but in my UI layer I think I need an extra attribute indicating whether the entity has been saved or not. How implement that ? I'm considering following option for the moment:

  • a JPA attribute with a default value set by the database, but would force a new read after each update ?
  • a non JPA attribute manually set in my code or automatically set by JPA?

Any advice / other suggestions ?

I'm using JPA 1 with Hibernate 3.2 implementation and would prefer stick to the standard.

+3  A: 

First, let's remind the various states of an entity. From the JPA 1.0 specification (in section 3.2 Entity Instance’s Life Cycle):

This section describes the EntityManager operations for managing an entity instance’s lifecycle. An entity instance may be characterized as being new, managed, detached, or removed.

  • A new entity instance has no persistent identity, and is not yet associated with a persistence context.
  • A managed entity instance is an instance with a persistent identity that is currently associated with a persistence context.
  • A detached entity instance is an instance with a persistent identity that is not (or no longer) associated with a persistence context.
  • A removed entity instance is an instance with a persistent identity, associated with a persistence context, that is scheduled for removal from the database.

And a graphical illustration:

alt text

So, by definition, a detached entity has already been persisted, and I actually don't think that this is your real question. Now, if you want to know if an entity is new (i.e. doesn't have any persistent identity), what about this:

@Transient
public boolean isNew() {
    return (this.id == null);
}
Pascal Thivent
Absolutely, I want to know if my entity is new. I would prefer use another field with a default value set in the database since I'm not using a JPA GeneratedValue strategy for the primary key (I'm setting myself the primary key with an UUID for cross database vendor/jpa implementation/clustering compatibility).
snowflake
@snowflake The problem is that JPA doesn't support database generated values for non pk attributes so you'll have to use a JPA provider extension (like `@org.hibernate.annotations.Generated`) or to refresh your entities after persist, which is ugly. I wonder if using `@GeneratedValue` wouldn't be a better choice.
Pascal Thivent
@Pascal Thivent Thank you for your comment. You're right this is ugly, I would prefer using as an alternative a field set in and by my DAO.
snowflake
Somewhere i read about using the @Version with a default value of null for this. You could than check if version != null as it should get updated every write. But, the example i saw was using xml. haven't tested it myself (yet)
bert