Search code examples
javajpaopenjpa

OpenJPA does not refresh entity on re-fetching of entity using JPQL(select query)


The question is specific to caching in Persistent Context(L1) and not to second level cache.

I want to know why entity in the cache of Persistent context are not refreshed on selection/re-loading of entity using JPQL.

Explanation of question using example:

  1. Start of transaction A
  2. Load entity A in the persistent context in transaction A.
  3. Some other processing in transaction A. But the loaded entity is not modified. At the same time, the same entity is modified and committed in another transaction B i.e. in another persistent context.
  4. Reload of entity A in transaction 1 using JPQL (select clause). Entity A has stale attributes.

I verified in the logs that query was fired. Then why was entity A not refreshed?


Solution

  • This is the way first level cache works. When OpenJPA reads the result set of the query, it checks the id field of the result set row. If the entity with that id is already present in the persistence context, the existing entity is used and the rest of the result set row is ignored, meaning that the entity is not assembled again.

    If you want to force reloading of an entity instance, you can:

    1. Refresh it.
    2. Detach it so that a new managed one will be loaded from the db when the persistence provider looks for it in any subsequent operation it performs.
    3. Clear the entire persistence context, so that the persistence provider reloads again everything it needs in any subsequent operation in the same transaction.

    Depending on the use cases, you may want to flush any changes you may have done in the instances you intend to refresh/detach/clear before applying any of the above operations, otherwise those changes will not be synchronized with the database.