Thursday, 20 August 2009

JPA Entity instances in the surgery



1. Introduction

This article focuses on the JPA entities state after applied CRUD operations. It also explains the real effect and the consequences of the CASCADE definition in the relationships between JPA entities.

2. Entity Instance’s Life Cycle

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






3. Persisting an Entity Instance


A new entity instance becomes both managed and persistent by invoking the persist method on it or by cascading the persist operation.
The semantics of the persist operation, applied to an entity X are as follows:


• If X is a new entity, it becomes managed. The entity X will be entered into the database at either before transaction commit or as a result of the flush operation.


• If X is a preexisting managed entity, it is ignored by the persist operation. However, the persist operation is cascaded to entities referenced by X, if the relationships from X to these other entities is annotated with the cascade=PERSIST or cascade=ALL annotation element value or specified with the equivalent XML descriptor element.


• If X is a removed entity, it becomes managed.


• If X is a detached object, the EntityExistsException may be thrown when the persist operation is invoked, or the EntityExistsException or another PersistenceException may be thrown at flush or commit time.


• For all entities Y referenced by a relationship from X, if the relationship to Y has been annotated with the cascade element value cascade=PERSIST or cascade=ALL, the persist operation is applied to Y.


4. Removal


A managed entity instance becomes removed by invoking the remove method on it or by cascading the remove operation.
The semantics of the remove operation, applied to an entity X are as follows:


• If X is a new entity, it is ignored by the remove operation. However, the remove operation is cascaded to entities referenced by X, if the relationship from X to these other entities is annotated with the cascade=REMOVE or cascade=ALL annotation element value.


• If X is a managed entity, the remove operation causes it to become removed. The remove operation is cascaded to entities referenced by X, if the relationships from X to these other entities is annotated with the cascade=REMOVE or cascade=ALL annotation element value.


• If X is a detached entity, an IllegalArgumentException will be thrown by the remove operation (or the transaction commit will fail).


• If X is a removed entity, it is ignored by the remove operation.


• A removed entity X will be removed from the database at or before transaction commit or as a result of the flush operation.


5. Synchronization to the Database


The state of persistent entities is synchronized to the database at transaction commit. This synchronization involving writing to the database any updates to persistent entities and their relationships as specified above.


An update to the state of an entity includes both the assignment of a new value to a persistent property or field of the entity as well as the modification of a mutable value of a persistent property or field.


Synchronization to the database does not involve a refresh of any managed entities unless the refresh operation is explicitly invoked on those entities.
The persistence provider runtime is permitted to perform synchronization to the database at other times as well when a transaction is active. The flush method can be used by the application to force synchronization.


It applies to entities associated with the persistence context.
The semantics of the flush operation, applied to an entity X are as follows:


• If X is a managed entity, it is synchronized to the database.


• For all entities Y referenced by a relationship from X, if the relationship to Y has been annotated with the cascade element value cascade=PERSIST or cascade= ALL, the persist operation is applied to Y.


• For any entity Y referenced by a relationship from X, where the relationship to Y has not been annotated with the cascade element value cascade=PERSIST or cascade= ALL:


• If Y is new or removed, an IllegalStateException will be thrown by the flush operation (and the transaction rolled back) or the transaction commit will fail.


• If Y is detached, the semantics depend upon the ownership of the relationship. If X owns  the relationship, any changes  to the relationship are synchronized with the database; otherwise, if Y owns the relationships, the behavior is  undefined.


• If X is a removed entity, it is removed from the database. No cascade options are relevant.


6. Detached Entities


A detached entity may result from:
·          transaction commit if a transaction-scoped container-managed entity manager is used
·          transaction rollback
·          clearing the persistence context
·          closing an entity manager
·          serializing an entity or otherwise passing an entity by value—e.g., to a separate application tier, through a remote interface, etc.


Detached entity instances continue to live outside of the persistence context in which they were persisted or retrieved, and their state is no longer guaranteed to be synchronized with the database state.


The application may access the available state of available detached entity instances after the persistence context ends. The available state includes:


• Any persistent field or property not marked fetch=LAZY


• Any persistent field or property that was accessed by the application


If the persistent field or property is an association, the available state of an associated instance may only be safely accessed if the associated instance is available. The available instances include:


• Any entity instance retrieved using find().


• Any entity instances retrieved using a query or explicitly requested in a FETCH JOIN clause.


• Any entity instance for which an instance variable holding non-primary-key persistent state was accessed by the application.


• Any entity instance that may be reached from another available instance by navigating associations marked fetch=EAGER.


7. Merging Detached Entity State


The merge operation allows for the propagation of state from detached entities onto persistent entities managed by the EntityManager.
The semantics of the merge operation applied to an entity X are as follows:


• If X is a detached entity, the state of X is copied onto a pre-existing managed entity instance X' of the same identity or a new managed copy X' of X is created.


• If X is a new entity instance, a new managed entity instance X' is created and the state of X is copied into the new managed entity instance X'.


• If X is a removed entity instance, an IllegalArgumentException will be thrown by the merge operation (or the transaction commit will fail).


• If X is a managed entity, it is ignored by the merge operation, however, the merge operation is cascaded to entities referenced by relationships from X if these relationships have been annotated with the cascade element value cascade=MERGE or cascade=ALL annotation.


• For all entities Y referenced by relationships from X having the cascade element value cascade=MERGE or cascade=ALL, Y is merged recursively as Y'. For all such Y referenced by X, X' is set to reference Y'. (Note that if X is managed then X is the same object as X'.)


• If X is an entity merged to X', with a reference to another entity Y, where cascade=MERGE or cascade=ALL is not specified, then navigation of the same association from X' yields a reference to a managed object Y' with the same persistent identity as Y.


8. Detached Entities and Lazy Loading


Serializing entities and merging those entities back into a persistence context may not be interoperable across vendors when lazy properties or fields and/or relationships are used.
A vendor is required to support the serialization and subsequent deserialization and merging of detached entity instances (which may contain lazy properties or fields and/or relationships that have not been fetched) back into a separate JVM instance of that vendor's runtime, where both runtime instances have access to the entity classes and any required vendor persistence implementation classes.


When interoperability across vendors is required, the application must not use lazy loading.


9. Managed Instances


It is the responsibility of the application to insure that an instance is managed in only a single persistence context. The behavior is undefined if the same Java instance is made managed in more than one persistence context.













1 comment:

  1. The idea of your blog is great. A place for publish and discuse common Java programming and J2EE topics like: transactions, concurrency, thread-safety, o/r mapping, data access design strategies, scalability, security,
    and mvc frameworks.

    ReplyDelete