Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "EclipseLink/UserGuide/JPA/Basic JPA Development/Caching/Shared and Isolated"

m
 
(31 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
{{EclipseLink_UserGuide|info=y
 
{{EclipseLink_UserGuide|info=y
|examples=y
+
|toc=y
|example=
+
|api=y
*[[EclipseLink/Examples/JPA/Caching|Caching]]
+
|apis=
 +
*[http://www.eclipse.org/eclipselink/api/latest/javax/persistence/Cacheable.html @Cacheable]
 +
*[http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/annotations/Cache.html @Cache]
 +
*[http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/config/CacheIsolationType.html CacheIsolationType]
 +
*[http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/config/ReferenceMode.html ReferenceMode]
 +
|napi=y
 +
|napis=
 +
*[http://www.eclipse.org/eclipselink/api/latest/org/eclipse/persistence/descriptors/CachePolicy.html CachePolicy]
 
}}
 
}}
  
=Shared and Isolated Cache=
+
=Shared, Isolated, Protected, Weak, and Read-only Cache=
 
+
EclipseLink defines three cache isolation levels.  The cache isolation level defines how caching for an entity is performed by the persistence unit and the persistence context.
 
+
 
+
  
 +
The cache isolation levels are:
 +
* Isolated - entities are only cached in the persistence context, not in the persistence unit.
 +
* Shared - entities are cached both in the persistence context and persistence unit, read-only entities are shared and only cached in the persistence unit.
 +
* Protected - entities are cached both in the persistence context and persistence unit, read-only entities are isolated and cached in the persistence unit and persistence context.
  
 
==Isolated Cache==
 
==Isolated Cache==
This caching technique always goes to the database for the initial read operation of an object whose descriptor is configured as isolated. By avoiding the shared session cache, you do not need to use the more complicated descriptor and query APIs to disable cache hits or always refresh.  
+
The isolated cache (L1) is the cache stored in the persistence context.  It is a transactional or user session based cache. Setting the cache isolation to <code>ISOLATED</code> for an entity disables its shared cache.  With an isolated cache all queries and find operations will access the database unless the object has already been read into the persistence context and refreshing is not used.
  
==Isolated Client Sessions==
+
Use a isolated cache to do the following:
 +
* avoid caching highly volatile data in the shared cache;
 +
* achieve serializable transaction isolation;
 +
* use the Oracle Virtual Private Database (VPD) feature (see [[#Oracle Virtual Private Database (VPD)|Oracle Virtual Private Database (VPD)]]).
  
An isolated client session is a special type of client session that provides its own session cache. This session cache is isolated from the shared session cache of its parent server session.
+
Each persistence context owns an initially empty isolated cache. The persistence context's isolated cache is discarded when the persistence context is closed, or the <code>EntityManager.clear()</code> operation is used.
  
Use isolated client sessions to do the following:
+
When you use an <code>EntityManager</code> to read an isolated entity, the <code>EntityManager</code> reads the entity directly from the database and stores it in the persistence context's isolated cache.  When you read a read-only entity it is still stored in the isolated cache, but is not change tracked.
* avoid caching highly volatile data in the shared session cache;
+
* achieve serializable transaction isolation (see [[Using%20Advanced%20Unit%20of%20Work%20API%20(ELUG)#Isolated Client Session Cache|Isolated Client Session Cache]]);
+
* use the Oracle Virtual Private Database (VPD) feature in your EclipseLink-enabled application (see [[#Isolated Client Sessions and Oracle Virtual Private Database (VPD)|Isolated Client Sessions and Oracle Virtual Private Database (VPD)]]).
+
  
If in your EclipseLink project you configure all classes as isolated (see [[Configuring%20a%20Project%20(ELUG)#Configuring Cache Isolation at the Project Level|Configuring Cache Isolation at the Project Level]]), or one or more classes as isolated (see [[Configuring%20a%20Descriptor%20(ELUG)#Configuring Cache Isolation at the Descriptor Level|Configuring Cache Isolation at the Descriptor Level]]), then all client sessions that you acquire from a parent server session will be isolated client sessions.
+
The persistence context can access the database using a connection pool or an exclusive connection. The persistence unit property <code>"eclipselink.jdbc.exclusive-connection.mode"</code> can be used to use an exclusive connection. Using an exclusive connection provides improved user-based security for reads and writes. Specific queries can also be configured to use the persistence context's exclusive connection.
 
+
This figure illustrates the relationship between a parent server session's shared session cache and its child isolated client sessions.
+
 
+
<span id="Figure 83-6"></span>
+
''''' Isolated Client Sessions'''''
+
 
+
[[Image:isolses.gif|Isolated Client Sessions]]<br><br>
+
 
+
Each isolated client session owns an initially empty cache and identity maps used exclusively for isolated objects that the isolated client session accesses while it is active. The isolated client session's isolated session cache is discarded when the isolated client session is released.
+
 
+
When you use an isolated client session to read an isolated class, the client session reads the isolated object directly from the database and stores it in that client session's isolated session cache. When you use the client session to read a shared class, the client session reads the shared object from the parent server session's shared session cache. If the shared object is not in the parent server session's shared session cache, it will read it from the database and store it in the parent server session's shared session cache.
+
 
+
Isolated objects in an isolated client session's isolated session cache may reference shared objects in the parent server session's shared session cache, but shared objects in the parent server session's shared session cache cannot reference isolated objects in an isolated client session's isolated session cache.
+
 
{{EclipseLink_Note
 
{{EclipseLink_Note
|note=You cannot define mappings from shared classes to isolated classes.
+
|note=If an <code>EntityManager</code> contains an exclusive connection, you must close the <code>EntityManager</code> when you are finished using it. We do not recommend relying on the finalizer to release the connection when the <code>EntityManager</code> is garbage-collected. If you are using a managed persistence context, then you do not need to close it.
 
}}
 
}}
  
 +
==Shared Cache==
 +
The shared cache (L2) is the cache stored in the persistence unit.  It is a shared object cache for the entire persistence unit.  Setting the cache isolation to <code>SHARED</code> for an entity enables its shared cache.  With a shared cache queries and find operations will resolve against the shared cache unless refreshing is used.
  
Client sessions can access the data source using a connection pool or an exclusive connection. To use an exclusive connection, acquire the isolated client session using a <tt>ConnectionPolicy</tt> (see [[Acquiring%20and%20Using%20Sessions%20at%20Run%20Time%20(ELUG)#How to Acquire a Client Session that Uses Exclusive Connections|How to Acquire a Client Session that Uses Exclusive Connections]]). Using an exclusive connection provides improved user-based security for reads and writes. Named queries can also use an exclusive connection (see [[Configuring%20a%20Descriptor%20(ELUG)#Configuring Named Query Advanced Options|Configuring Named Query Advanced Options]]).
+
Use a shared cache to do the following:
{{EclipseLink_Note
+
* improve performance by avoiding database access when finding or querying an entity by Id or index;
|note=If an isolated session contains an exclusive connection, you must release the session when you are finished using it. We do not recommend relying on the finalizer to release the connection when the session is garbage-collected. If you are using an active unit of work in a JTA transaction, you do not need to release the client session–-the unit of work will release it after the JTA transaction completes.
+
* improve performance by avoiding database access when accessing an entity's relationships;
}}
+
* preserve object identity across persistence contexts for read-only entities.
  
 +
When you use an <code>EntityManager</code> to find a shared entity, the <code>EntityManager</code> first checks the persistence unit's shared cache. If the entity is not in the persistence unit's shared cache, it will be read from the database and stored in the persistence unit's shared cache, a copy will also be stored in the persistence context's isolated cache.  Any query not by Id, and not by an indexed attribute will first access the database.  For each query result row, if the object is already in the shared cache, the shared object (with its relationships) will be used, otherwise a new object will be built from the row and put into the shared cache, and a copy will be put into the isolated cache.  The isolated copy is always returned, unless read-only is used.  For read-only the shared object is returned as the isolated copy is not required.
  
For more information, see the following:
+
The size and memory usage of the shared cache depends on the entities cache type.  The JPA <code>Cache</code> and EclipseLink <code>JpaCache</code> can also be used to invalidate or clear the cache.
* [[#Isolated Client Session Limitations|Isolated Client Session Limitations]]
+
* [[Acquiring%20and%20Using%20Sessions%20at%20Run%20Time%20(ELUG)#How to Acquire an Isolated Client Session|How to Acquire an Isolated Client Session]]
+
* [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)|Configuring Exclusive Isolated Client Sessions for Virtual Private Database]]
+
  
 +
==Protected Cache==
 +
The protected cache option allows for shared objects to reference isolated objects.  Setting the cache isolation to <code>PROTECTED</code> for an entity enables its shared cache. The protected option is mostly the same as the shared option, except that protected entities can have relationships to isolated entities, where as shared can not.
  
===Isolated Client Sessions and Oracle Virtual Private Database (VPD)===
+
Use a protected cache to do the following:
Oracle9''i'' Database Server (and later) provides a server-enforced, fine-grained access control mechanism called Virtual Private Database (VPD). VPD ties a security policy to a table by dynamically appending SQL statements with a predicate to limit data access at the row level. You can create your own security policies, or use Oracle's custom implementation of VPD called Oracle Label Security (OLS). For more information on VPD and OLS, see the following:
+
* improve performance by avoiding database access when finding or querying an entity by Id or index;
 +
* improve performance by avoiding database access when accessing an entity's relationships to shared entities;
 +
* ensure read-only entities are isolated to the persistence context;
 +
* allow relationships to isolated entities.
  
<tt>http://www.oracle.com/technology/deploy/security/index.html</tt>.
+
Protected entities have the same life-cycle as shared entities, except for relationships, and read-only. Protected entities relationships to shared entities are cached in the shared cache, but their relationships to isolated entities are isolated and not cached in the shared cache. The <code>@Noncacheable</code> annotation can also be used to disable caching of a relationship to shared entities.  Protected entities that are read-only are always copied into the isolated cache, but are not change tracked.
  
 +
==Cache Isolation Examples==
 +
======''Isolated cache annotation example''======
 +
<source lang="java">
 +
...
 +
@Entity
 +
@Cache(
 +
  isolation=CacheIsolationType.ISOLATED
 +
)
 +
public class Employee {
 +
  ...
 +
}
 +
</source>
  
To use the Oracle Database VPD feature in your EclipseLink-enabled application, use isolated client sessions.
+
======''Protected cache annotation example''======
 +
<source lang="java">
 +
@Entity
 +
@Cache(
 +
  isolation=CacheIsolationType.PROTECTED
 +
)
 +
public class Employee {
 +
  @Id
 +
  private long id;
 +
  ...
 +
  @OneToMany(mappedBy="manager")
 +
  @Noncacheable
 +
  private List<Employee> managedEmployees;
 +
  ...
 +
}
 +
</source>
  
Any class that maps to a table that uses VPD must have the descriptor configured as isolated (see [[Configuring%20a%20Descriptor%20(ELUG)#Configuring Cache Isolation at the Descriptor Level|Configuring Cache Isolation at the Descriptor Level]]).
+
======''Isolated cache XML example''======
 +
<source lang="xml">
 +
<?xml version="1.0"?>
 +
<entity-mappings
 +
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"
 +
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 +
xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_2_4.xsd"
 +
version="2.4">
 +
    <entity name="Employee" class="org.acme.Employee" access="FIELD">
 +
        <cache isolation="ISOLATED"/>
 +
    </entity>
 +
</entity-mappings>
 +
</source>
  
When you use isolated client sessions with VPD, you typically use exclusive connections (see [[Acquiring%20and%20Using%20Sessions%20at%20Run%20Time%20(ELUG)#How to Acquire a Client Session that Uses Exclusive Connections|How to Acquire a Client Session that Uses Exclusive Connections]]).
+
======''Protected cache XML example''======
 +
<source lang="xml">
 +
<?xml version="1.0"?>
 +
<entity-mappings
 +
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"
 +
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 +
xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_2_4.xsd"
 +
version="2.4">
 +
    <entity name="Employee" class="org.acme.Employee" access="FIELD">
 +
        <cache isolation="PROTECTED"/>
 +
        <attributes>
 +
            <id name= "id"/>
 +
            <one-to-many name="managedEmployees" mapped-by="manager">
 +
                <noncacheable/>
 +
            </one-to-many>
 +
        </attributes>
 +
    </entity>
 +
</entity-mappings>
 +
</source>
  
To support VPD, you are responsible for implementing session event handlers that the EclipseLink runtime invokes during the isolated client session life cycle (see [[#Isolated Client Session Life Cycle|Isolated Client Session Life Cycle]]). The session event handler you must implement depends on whether or not you are using Oracle Database proxy authentication (see [[#VPD with Oracle Database Proxy Authentication|VPD with Oracle Database Proxy Authentication]] and [[#VPD Without Oracle Database Proxy Authentication|VPD Without Oracle Database Proxy Authentication]]).
+
==Weak Reference Mode==
 +
EclipseLink offers a specialized persistence context cache for long-lived persistence contexts. Normally it is best to keep persistence contexts short-lived, such as creating a new <code>EntityManager</code> per request, or per transaction.  This is referred to as a stateless model.  This ensures the persistence context does not become too big, causing memory and performance issues.  It also ensures the objects cached in the persistence context do not become stale or out of sync with their committed state.
  
For information, see [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)|Configuring Exclusive Isolated Client Sessions for Virtual Private Database]].
+
Some two-tier applications, or stateful models require long-lived persistence contexts.  EclipseLink offers a special <i>weak reference mode</i> option for these types of applications.  A weak reference mode maintains weak references to the objects in the persistence context.  This allows the objects to garbage collect if not referenced by the application.  This helps prevent the persistence context from becoming too big, reducing memory usage and improving performance.  Any new, removed or changed objects will be held with strong references until a commit occurs.
  
 +
A weak reference mode can be configured through the <code>"eclipselink.persistence-context.reference-mode"</code> persistence unit property.
 +
The following options can be used:
 +
* <code>HARD</code> - This is the default, weak references are not used.  The persistence context will grow until cleared or closed.
 +
* <code>WEAK</code> - Weak references are used.  Unreferenced unchanged objects will be free to garbage collect.  Objects that use deferred change tracking will not be free to garbage collect.
 +
* <code>FORCE_WEAK</code> - Weak references are used.  Unreferenced unchanged objects will be free to garbage collect.  Unreferenced changed objects that use deferred change tracking will also be free to garbage collection, causing any changes to be lost.
  
====VPD with Oracle Database Proxy Authentication====
+
==Read-Only Entities==
If you are using Oracle Database proxy authentication ( [[Introduction%20to%20Data%20Access%20(ELUG)#Oracle Database Proxy Authentication|Oracle Database Proxy Authentication]]), you must implement a session event handler for the following session events:
+
An entity can be configured as read-only using the <code>@ReadOnly</code> annotation or the <code>read-only</code> XML attribute.  A read-only entity will not be tracked for changes and any updates will be ignored.  Read-only entities cannot be persisted or removed.  An read-only entity must not be modified, but EclipseLink does not currently enforce this, modification  to read-only objects can corrupt the persistence unit cache.
* <tt>noRowsModifiedSessionEvent</tt> (see [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)#Using NoRowsModifiedSessionEvent Event Handler|Using NoRowsModifiedSessionEvent Event Handler]])
+
  
By using Oracle Database proxy authentication, you can set up VPD support entirely in the database. That is, rather than making the isolated client session execute SQL (see [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)#Using PostAcquireExclusiveConnection Event Handler|Using PostAcquireExclusiveConnection Event Handler]] and [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)#Using PreReleaseExclusiveConnection Event Handler|Using PreReleaseExclusiveConnection Event Handler]]), the database performs the required setup in an after login trigger using the proxy <tt>session_user</tt>.
+
Queries can also be configured to return read-only objects using the <code>"eclipselink.read-only"</code> query hint.
  
 +
A <code>SHARED</code> entity that is read-only will return the shared instance from queries.  The same entity will be returned from all queries from all persistence contexts.  Shared read-only entities will never be copied or isolated in the persistence context.  This improves performance by avoiding the cost of copying the object, and tracking the object for changes.  This both reduces memory, reduces heap usage, and improves performance.  Object identity is also maintained across the entire persistence unit for read-only entities, allowing the application to hold references to these shared objects.
  
====VPD Without Oracle Database Proxy Authentication====
+
An <code>ISOLATED</code> or <code>PROTECTED</code> entity that is read-only will still have an isolated copy returned from the persistence context.  This gives some improvement in performance and memory usage from avoid tracking the object for changes, but it is not as significant as <code>SHARED</code> entities.
If you are not using Oracle Database proxy authentication, you must implement session event handlers for the following session events:
+
* <tt>postAcquireExclusiveConnection</tt> (see [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)#Using PostAcquireExclusiveConnection Event Handler|Using PostAcquireExclusiveConnection Event Handler]]): used to perform VPD setup at the time EclipseLink allocates a dedicated connection to an isolated session and before the isolated session user uses the connection to interact with the database.
+
* <tt>preReleaseExclusiveConnection</tt> (see [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)#Using PreReleaseExclusiveConnection Event Handler|Using PreReleaseExclusiveConnection Event Handler]]): used to perform VPD cleanup at the time the isolated session is released and after the user is finished interacting with the database.
+
* <tt>noRowsModifiedSessionEvent</tt> (see [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)#Using NoRowsModifiedSessionEvent Event Handler|Using NoRowsModifiedSessionEvent Event Handler]])
+
  
In your implementation of these handlers, you obtain the required user credentials from the <tt>ConnectionPolicy</tt> associated with the session (see [[Acquiring%20and%20Using%20Sessions%20at%20Run%20Time%20(ELUG)#How to Acquire a Client Session that Uses Connection Properties|How to Acquire a Client Session that Uses Connection Properties]]).
+
==Oracle Virtual Private Database (VPD)==
 +
Oracle Database Server provides a server-enforced, fine-grained access control mechanism called Virtual Private Database (VPD). VPD ties a security policy to a table by dynamically appending SQL statements with a predicate to limit data access at the row level. You can create your own security policies, or use Oracle's custom implementation of VPD called Oracle Label Security (OLS). For more information on VPD and OLS, see the following:
  
 +
<tt>http://www.oracle.com/technology/deploy/security/index.html</tt>.
  
====Isolated Client Session Life Cycle====
 
This section provides an overview of the key phases in the life cycle of an isolated session, including the following:
 
* Setup required before using an isolated session
 
* Interaction among isolated session objects
 
* Clean-up required after using an isolated session
 
  
To enable the life cycle of an isolated session, use this procedure:
+
To use the Oracle Database VPD feature in your EclipseLink-enabled application, an isolated cache should be used.
<ol>
+
<li>Prepare VPD configuration in the database.</li>
+
<li> Configure your project and session:
+
<ul>
+
<li> Designate descriptors as isolated (see [[Configuring%20a%20Descriptor%20(ELUG)#Configuring Cache Isolation at the Descriptor Level|Configuring Cache Isolation at the Descriptor Level]]).</li>
+
<li> Configure your server session to allocate exclusive connections (see [[Configuring%20a%20Session%20(ELUG)#Configuring Connection Policy|onfiguring Connection Policy]]).</li>
+
<li> Implement session event listeners for the required connection events:
+
<ul><li>If you are using [[Introduction%20to%20Data%20Access%20(ELUG)#Oracle Database Proxy Authentication|Oracle Database proxy authentication]], see [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)#Using NoRowsModifiedSessionEvent Event Handler|Using NoRowsModifiedSessionEvent Event Handler]].</li>
+
<li> If you are not using Oracle Database proxy authentication, see [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)#Using PostAcquireExclusiveConnection Event Handler|Using PostAcquireExclusiveConnection Event Handler]], [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)#Using PreReleaseExclusiveConnection Event Handler|Using PreReleaseExclusiveConnection Event Handler]], and [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)#Using NoRowsModifiedSessionEvent Event Handler|Using NoRowsModifiedSessionEvent Event Handler]]<br><table class="Note oac_no_warn" width="80%" border="1" frame="hsides" rules="groups" cellpadding="3" frame="hsides" rules="groups"><tr><td>'''Note:''' You must add these session event listeners to the server session from which you acquire your isolated client session. You cannot add them to the isolated client session itself. For more information, see [[Configuring%20a%20Session%20(ELUG)#Configuring Session Event Listeners|Configuring Session Event Listeners]]</td></tr></table></li></ul></li>
+
<li>Implement exception handlers for the appropriate exceptions (see [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)#Using ValidationException Handler|Using ValidationException Handler]]).</li>
+
</ul>
+
<li> Acquire an isolated session:
+
<ul>
+
<li> If you are using [[Introduction%20to%20Data%20Access%20(ELUG)#Oracle Database Proxy Authentication|Oracle Database proxy authentication]]:
+
<br>
+
<div class="pre">
+
Session myIsolatedClientSession = <br>server.acquireClientSession();
+
</div>
+
<br>Because you configured one or more descriptors as isolated, <tt>myIsolatedClientSession</tt> is an isolated session with an exclusive connection.</li>
+
<li> If you are not using Oracle Database proxy authentication:
+
<br>
+
<div class="pre">
+
ConnectionPolicy myConnPolicy = (ConnectionPolicy)server.getDefaultConnectionPolicy().clone();
+
myConnectionPolicy.setProperty("credentials", myUserCredentials);
+
Session myIsolatedClientSession = server.acquireClientSession(myConnectionPolicy);
+
</div>
+
<br>
+
Set the user's credentials as appropriate properties on <tt>myConnectionPolicy</tt>. Because you configured one or more descriptors as isolated, <tt>myIsolatedClientSession</tt> is an isolated session with an exclusive connection.<br>The EclipseLink runtime raises a <tt>SessionEvent.PostAcquireExclusiveConnection</tt> event handled by your <tt>SessionEventListener</tt> (see [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)#CIHJFGFD|Using PostAcquireExclusiveConnection Event Handler]]).</li>
+
</ul>
+
</li>
+
<li> Use <tt>myIsolatedClientSession</tt> to interact with the database.<br>If the EclipseLink runtime raises a <tt>SessionEvent.NoRowsModified</tt> event, it is handled by your <tt>SessionEventListener</tt> (see [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)#CIHHJCDG|Using NoRowsModifiedSessionEvent Event Handler]]).</li>
+
<li> When you are finished using <tt>myIsolatedClientSession</tt>, release the isolated session:<br>
+
<div class="pre">
+
myIsolatedClientSession.release();
+
</div>
+
<br>The EclipseLink runtime prepares to destroy the isolated cache and to close the exclusive connection associated with this isolated session.<br>The EclipseLink runtime raises a <tt>SessionEvent.PreReleaseExclusiveConnection</tt> event handled by your <tt>SessionEventListener</tt> (see [[Configuring%20Exclusive%20Isolated%20Client%20Sessions%20for%20Virtual%20Private%20Database%20(ELUG)#CIHEEIEF|Using PreReleaseExclusiveConnection Event Handler]]).</li>
+
<li> Repeat steps #3 to #5 (as required) until the application exits.</li>
+
</ol>
+
  
===Isolated Client Session Limitations===
+
Any entity that maps to a table that uses VPD should have the descriptor configured as isolated.
For the purposes of security as well as efficiency, observe the limitations described in the following section, when you use isolated client sessions in your EclipseLink three-tier application:
+
* [[#Mapping|Mapping]]
+
* [[#Inheritance|Inheritance]]
+
* [[#Caching and Cache Coordination|Caching and Cache Coordination]]
+
* [[#Sequencing|Sequencing]]
+
* [[#Transactions and JTA|Transactions and JTA]]
+
  
 +
When you use VPD, you typically should also use exclusive connections.
  
===='''Mapping'''====
+
To support VPD, you are responsible for implementing session event handlers that the EclipseLink runtime invokes during the persistence context's life cycle. The session event handler you must implement depends on whether or not you are using Oracle Database proxy authentication (see [[#VPD with Oracle Database Proxy Authentication|VPD with Oracle Database Proxy Authentication]] and [[#VPD Without Oracle Database Proxy Authentication|VPD Without Oracle Database Proxy Authentication]]).
Consider the following mapping and relationship restrictions when using isolated sessions with your relational model:
+
* Isolated objects may be related to shared objects, but shared objects cannot have any relationships with isolated objects.
+
* If a table has a VPD security policy associated with it, then the class mapped to that table must be isolated.
+
* If one of the tables in a multiple table mapping is isolated, then the main class must also be isolated.
+
  
The EclipseLink runtime enforces these restrictions during descriptor initialization.
+
====VPD with Oracle Database Proxy Authentication====
 +
By using Oracle Database proxy authentication, you can set up VPD support entirely in the database. That is, rather than session event handlers to execute SQL, the database performs the required setup in an after login trigger using the proxy <tt>session_user</tt>.
  
 +
====VPD Without Oracle Database Proxy Authentication====
 +
If you are not using Oracle Database proxy authentication, you must implement session event handlers for the following session events:
 +
* <tt>postAcquireExclusiveConnection</tt>: used to perform VPD setup at the time EclipseLink allocates a dedicated connection to an isolated session and before the isolated session user uses the connection to interact with the database.
 +
* <tt>preReleaseExclusiveConnection</tt>: used to perform VPD cleanup at the time the isolated session is released and after the user is finished interacting with the database.
  
===='''Inheritance'''====
+
In your implementation of these handlers, you can obtain the required user credentials from the associated session's properties.
Aggregates and aggregate mappings inherit the isolated configuration of their parents.
+
 
+
If a class is isolated, then all inheriting classes should be isolated. Otherwise, if you relate a shared class to a shared superclass with isolated subclasses, it is possible that some of the isolated subclasses will lose object identity when the isolated session is released.
+
 
+
To give you the flexibility to mix shared and isolated classes, the EclipseLink runtime does not enforce these restrictions during descriptor initialization. If you wish to mix shared and isolated classes in your inheritance hierarchy, then you must be prepared to deal with this possible loss of object identity.
+
 
+
 
+
===='''Caching and Cache Coordination'''====
+
Isolated classes are never loaded into the shared cache of a parent server session. Isolated classes cannot be used with cache coordination.
+
 
+
 
+
===='''Sequencing'''====
+
We recommend that you do not configure a sequencing object or sequence table using VPD security. EclipseLink does not access sequencing objects using the isolated session's dedicated connection, and so VPD restricted sequence values are not available to the isolated session.  Sequence objects not using VPD security are fine.
+
 
+
===='''Transactions and JTA'''====
+
We recommend that you explicitly release an isolated session when you are finished using it, rather than wait for the Java garbage collector to invoke the finalizer. The finalizer is provided as a last resort: waiting for the garbage collector may cause errors when dealing with a JTA transaction.
+
 
+
  
 
{{EclipseLink_JPA
 
{{EclipseLink_JPA
|previous=[[EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching/Cache Annotation|@Cache Annotation]]
+
|previous=[[EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching/Configuring|Configuring Caching]]
 
|next=[[EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching/Type and Size|Cache Type and Size]]
 
|next=[[EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching/Type and Size|Cache Type and Size]]
 
|up=[[EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching|Caching]]
 
|up=[[EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching|Caching]]
|version=2.2.0 DRAFT}}
+
|version=2.4 DRAFT}}

Latest revision as of 13:47, 29 May 2012


Shared, Isolated, Protected, Weak, and Read-only Cache

EclipseLink defines three cache isolation levels. The cache isolation level defines how caching for an entity is performed by the persistence unit and the persistence context.

The cache isolation levels are:

  • Isolated - entities are only cached in the persistence context, not in the persistence unit.
  • Shared - entities are cached both in the persistence context and persistence unit, read-only entities are shared and only cached in the persistence unit.
  • Protected - entities are cached both in the persistence context and persistence unit, read-only entities are isolated and cached in the persistence unit and persistence context.

Isolated Cache

The isolated cache (L1) is the cache stored in the persistence context. It is a transactional or user session based cache. Setting the cache isolation to ISOLATED for an entity disables its shared cache. With an isolated cache all queries and find operations will access the database unless the object has already been read into the persistence context and refreshing is not used.

Use a isolated cache to do the following:

  • avoid caching highly volatile data in the shared cache;
  • achieve serializable transaction isolation;
  • use the Oracle Virtual Private Database (VPD) feature (see Oracle Virtual Private Database (VPD)).

Each persistence context owns an initially empty isolated cache. The persistence context's isolated cache is discarded when the persistence context is closed, or the EntityManager.clear() operation is used.

When you use an EntityManager to read an isolated entity, the EntityManager reads the entity directly from the database and stores it in the persistence context's isolated cache. When you read a read-only entity it is still stored in the isolated cache, but is not change tracked.

The persistence context can access the database using a connection pool or an exclusive connection. The persistence unit property "eclipselink.jdbc.exclusive-connection.mode" can be used to use an exclusive connection. Using an exclusive connection provides improved user-based security for reads and writes. Specific queries can also be configured to use the persistence context's exclusive connection.

Elug note icon.png

Note: If an EntityManager contains an exclusive connection, you must close the EntityManager when you are finished using it. We do not recommend relying on the finalizer to release the connection when the EntityManager is garbage-collected. If you are using a managed persistence context, then you do not need to close it.

Shared Cache

The shared cache (L2) is the cache stored in the persistence unit. It is a shared object cache for the entire persistence unit. Setting the cache isolation to SHARED for an entity enables its shared cache. With a shared cache queries and find operations will resolve against the shared cache unless refreshing is used.

Use a shared cache to do the following:

  • improve performance by avoiding database access when finding or querying an entity by Id or index;
  • improve performance by avoiding database access when accessing an entity's relationships;
  • preserve object identity across persistence contexts for read-only entities.

When you use an EntityManager to find a shared entity, the EntityManager first checks the persistence unit's shared cache. If the entity is not in the persistence unit's shared cache, it will be read from the database and stored in the persistence unit's shared cache, a copy will also be stored in the persistence context's isolated cache. Any query not by Id, and not by an indexed attribute will first access the database. For each query result row, if the object is already in the shared cache, the shared object (with its relationships) will be used, otherwise a new object will be built from the row and put into the shared cache, and a copy will be put into the isolated cache. The isolated copy is always returned, unless read-only is used. For read-only the shared object is returned as the isolated copy is not required.

The size and memory usage of the shared cache depends on the entities cache type. The JPA Cache and EclipseLink JpaCache can also be used to invalidate or clear the cache.

Protected Cache

The protected cache option allows for shared objects to reference isolated objects. Setting the cache isolation to PROTECTED for an entity enables its shared cache. The protected option is mostly the same as the shared option, except that protected entities can have relationships to isolated entities, where as shared can not.

Use a protected cache to do the following:

  • improve performance by avoiding database access when finding or querying an entity by Id or index;
  • improve performance by avoiding database access when accessing an entity's relationships to shared entities;
  • ensure read-only entities are isolated to the persistence context;
  • allow relationships to isolated entities.

Protected entities have the same life-cycle as shared entities, except for relationships, and read-only. Protected entities relationships to shared entities are cached in the shared cache, but their relationships to isolated entities are isolated and not cached in the shared cache. The @Noncacheable annotation can also be used to disable caching of a relationship to shared entities. Protected entities that are read-only are always copied into the isolated cache, but are not change tracked.

Cache Isolation Examples

Isolated cache annotation example
...
@Entity
@Cache(
  isolation=CacheIsolationType.ISOLATED
)
public class Employee {
  ...
}
Protected cache annotation example
@Entity
@Cache(
  isolation=CacheIsolationType.PROTECTED
)
public class Employee {
  @Id
  private long id;
  ...
  @OneToMany(mappedBy="manager")
  @Noncacheable
  private List<Employee> managedEmployees;
  ...
}
Isolated cache XML example
<?xml version="1.0"?>
<entity-mappings
	xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_2_4.xsd"
	version="2.4">
    <entity name="Employee" class="org.acme.Employee" access="FIELD">
        <cache isolation="ISOLATED"/>
    </entity>
</entity-mappings>
Protected cache XML example
<?xml version="1.0"?>
<entity-mappings
	xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_2_4.xsd"
	version="2.4">
    <entity name="Employee" class="org.acme.Employee" access="FIELD">
        <cache isolation="PROTECTED"/>
        <attributes>
            <id name= "id"/>
            <one-to-many name="managedEmployees" mapped-by="manager">
                <noncacheable/>
            </one-to-many>
        </attributes>
    </entity>
</entity-mappings>

Weak Reference Mode

EclipseLink offers a specialized persistence context cache for long-lived persistence contexts. Normally it is best to keep persistence contexts short-lived, such as creating a new EntityManager per request, or per transaction. This is referred to as a stateless model. This ensures the persistence context does not become too big, causing memory and performance issues. It also ensures the objects cached in the persistence context do not become stale or out of sync with their committed state.

Some two-tier applications, or stateful models require long-lived persistence contexts. EclipseLink offers a special weak reference mode option for these types of applications. A weak reference mode maintains weak references to the objects in the persistence context. This allows the objects to garbage collect if not referenced by the application. This helps prevent the persistence context from becoming too big, reducing memory usage and improving performance. Any new, removed or changed objects will be held with strong references until a commit occurs.

A weak reference mode can be configured through the "eclipselink.persistence-context.reference-mode" persistence unit property. The following options can be used:

  • HARD - This is the default, weak references are not used. The persistence context will grow until cleared or closed.
  • WEAK - Weak references are used. Unreferenced unchanged objects will be free to garbage collect. Objects that use deferred change tracking will not be free to garbage collect.
  • FORCE_WEAK - Weak references are used. Unreferenced unchanged objects will be free to garbage collect. Unreferenced changed objects that use deferred change tracking will also be free to garbage collection, causing any changes to be lost.

Read-Only Entities

An entity can be configured as read-only using the @ReadOnly annotation or the read-only XML attribute. A read-only entity will not be tracked for changes and any updates will be ignored. Read-only entities cannot be persisted or removed. An read-only entity must not be modified, but EclipseLink does not currently enforce this, modification to read-only objects can corrupt the persistence unit cache.

Queries can also be configured to return read-only objects using the "eclipselink.read-only" query hint.

A SHARED entity that is read-only will return the shared instance from queries. The same entity will be returned from all queries from all persistence contexts. Shared read-only entities will never be copied or isolated in the persistence context. This improves performance by avoiding the cost of copying the object, and tracking the object for changes. This both reduces memory, reduces heap usage, and improves performance. Object identity is also maintained across the entire persistence unit for read-only entities, allowing the application to hold references to these shared objects.

An ISOLATED or PROTECTED entity that is read-only will still have an isolated copy returned from the persistence context. This gives some improvement in performance and memory usage from avoid tracking the object for changes, but it is not as significant as SHARED entities.

Oracle Virtual Private Database (VPD)

Oracle Database Server provides a server-enforced, fine-grained access control mechanism called Virtual Private Database (VPD). VPD ties a security policy to a table by dynamically appending SQL statements with a predicate to limit data access at the row level. You can create your own security policies, or use Oracle's custom implementation of VPD called Oracle Label Security (OLS). For more information on VPD and OLS, see the following:

http://www.oracle.com/technology/deploy/security/index.html.


To use the Oracle Database VPD feature in your EclipseLink-enabled application, an isolated cache should be used.

Any entity that maps to a table that uses VPD should have the descriptor configured as isolated.

When you use VPD, you typically should also use exclusive connections.

To support VPD, you are responsible for implementing session event handlers that the EclipseLink runtime invokes during the persistence context's life cycle. The session event handler you must implement depends on whether or not you are using Oracle Database proxy authentication (see VPD with Oracle Database Proxy Authentication and VPD Without Oracle Database Proxy Authentication).

VPD with Oracle Database Proxy Authentication

By using Oracle Database proxy authentication, you can set up VPD support entirely in the database. That is, rather than session event handlers to execute SQL, the database performs the required setup in an after login trigger using the proxy session_user.

VPD Without Oracle Database Proxy Authentication

If you are not using Oracle Database proxy authentication, you must implement session event handlers for the following session events:

  • postAcquireExclusiveConnection: used to perform VPD setup at the time EclipseLink allocates a dedicated connection to an isolated session and before the isolated session user uses the connection to interact with the database.
  • preReleaseExclusiveConnection: used to perform VPD cleanup at the time the isolated session is released and after the user is finished interacting with the database.

In your implementation of these handlers, you can obtain the required user credentials from the associated session's properties.

Eclipselink-logo.gif
Version: 2.4 DRAFT
Other versions...

Back to the top