Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA: Extending the persistence context vs. detaching entities

There appear to be two patterns to implement business transactions that span several http requests with JPA:

  1. entity-manager-per-request with detached entities
  2. extended persistence context

What are the respective advantages of these patterns? When should which be preferred?

So far, I came up with:

  • an extended persistence context guarantees that object identity is equivalent to database identity, simplifying the programming model and potentially disspelling the need to implement equals for entities
  • detached entities require less memory than an extended persistence context, as the persistence context also has to store the previous state of the entity for change detection
  • no longer referenced detached entities become eligible for garbage collection; persistent objects must first be detached explicitly

However, not having any practical experience with JPA I am sure I have missed something of importance, hence this question.

In case it matters: We intend to use JPA 2.0 backed by Hibernate 3.6.

Edit: Our view technology is JSF 2.0, in an EJB 3.1 container, with CDI and possibly Seam 3.

like image 472
meriton Avatar asked Jun 21 '11 21:06

meriton


People also ask

What is extended persistence context?

Extended Persistence Context. A persistence context is a set of entities such that for any persistent identity there is a unique entity instance. Within a persistence context, entities are managed.

When the JPA entities will become detached?

When the transaction (in transaction-scoped persistence context) commits, entities managed by the persistence context become detached. If an application-managed persistence context is closed, all managed entities become detached. Using clear method.

How do you remove entity from persistence context?

You can prevent that by calling the flush method on the EntityManager. After you've done that, you can remove a specific entity from the persistence context by calling the detach method or you can call the clear method to clear the persistence context completely. Query query = em.

What is difference between EntityManagerFactory and SessionFactory?

Using EntityManagerFactory approach allows us to use callback method annotations like @PrePersist, @PostPersist,@PreUpdate with no extra configuration. Using similar callbacks while using SessionFactory will require extra efforts.


1 Answers

Well, I can enumerate challenges with trying to use extended persistence contexts in a web environment. Some things also depend on what your view technology is and if it's binding entities or view level middlemen.

  1. EntityManagers are not threadsafe. You don't need one per user session. You need one per user session per browser tab.
  2. When an exception comes out of an EntityManager, it is considered invalid and needs to be closed and replaced. If you're planning to write your own framework extensions for managing the extended lifecycle, the implementation of this needs to be bullet proof. Generally in an EM-per-request setup the exception goes to some kind of error page and then loading the next page creates a new one anyway like it always would have.
  3. Object equality is not going to be 100% automagically safe. As above, an exception may have invalidated the context an object loaded earlier was associated with, so one fetched now will not be equal. Making that assumption also assumes an extremely high level of skill and understanding of how JPA works and what the EM does among the developers using it. e.g., accidentally using merge when it wasn't needed will return a new object which will not satisfy == with its field-identical predecessor. (treating merge like a SQL 'update' is an extremely common JPA noobie 'error' particularly because it's just a no-op most of the time so it slides past.)
  4. If you're using a view technology that binds POJOs (e.g., SpringMVC) and you're planning to bind web form data directly onto your Entities, you'll get in trouble quick. Changes to an attached entity will become persistent on the next flush/commit, regardless of whether they were done in a transaction or not. Common error is, web form comes in and binds some invalid data onto an entity, validation fails and trys to return a screen to inform user. Building error screen involves running a query. Query triggers flush/commit of persistence context. Changes bound to attached entity get flushed to database, hopefully causing SQL exception, but maybe just persisting corrupt data.

(Problem 4 can of course also happen with session per request if the programming is sloppy, but you're not forced to actively work hard at avoiding it.)

like image 129
Affe Avatar answered Sep 22 '22 18:09

Affe