deltaspike-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From build...@apache.org
Subject svn commit: r905822 - in /websites/staging/deltaspike/trunk/content: ./ jpa.html
Date Fri, 11 Apr 2014 15:45:04 GMT
Author: buildbot
Date: Fri Apr 11 15:45:04 2014
New Revision: 905822

Log:
Staging update by buildbot for deltaspike

Modified:
    websites/staging/deltaspike/trunk/content/   (props changed)
    websites/staging/deltaspike/trunk/content/jpa.html

Propchange: websites/staging/deltaspike/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Fri Apr 11 15:45:04 2014
@@ -1 +1 @@
-1585176
+1586690

Modified: websites/staging/deltaspike/trunk/content/jpa.html
==============================================================================
--- websites/staging/deltaspike/trunk/content/jpa.html (original)
+++ websites/staging/deltaspike/trunk/content/jpa.html Fri Apr 11 15:45:04 2014
@@ -82,6 +82,7 @@
 <ul>
 <li><a href="#transactional">@Transactional</a></li>
 <li><a href="#transactionscoped">@TransactionScoped</a></li>
+<li><a href="#extended-persistence-contexts">Extended Persistence Contexts</a></li>
 <li><a href="#jta-support">JTA Support</a></li>
 </ul>
 </div>
@@ -382,6 +383,95 @@ So it's possible to catch an exception i
 </pre></div>
 
 
+<h1 id="extended-persistence-contexts">Extended Persistence Contexts</h1>
+<p>Frameworks like MyFaces Orchestra provide a feature which allows keeping an <code>EntityManager</code>
across multiple requests. That means it isn't required to call <code>EntityManager#merge</code>
to add detached entities to the context. However, several application architectures don't
allow such an approach (due to different reasons like scalability). In theory that sounds
nice and it works pretty well for small to medium sized projects esp. if an application doesn't
rely on session replication in clusters. That also means that such an approach restricts your
target environment from the very beginning. One of the base problems is that an <code>EntityManager</code>
isn't serializable. Beans which are scoped in a normal-scoped CDI context have to be serializable.
So by default it isn't allowed by CDI to provide a producer-method which exposes e.g. a conversation
scoped <code>EntityManager</code> as it is. We <strong>don't</strong>
recommend to use this approach and therefore it 
 isn't available out-of-the-box. However, if you really need this approach to avoid calling
<code>#merge</code> for your detached entities, it's pretty simple to add this
functionality.</p>
+<p>Usage of a simple <code>ExtendedEntityManager</code></p>
+<div class="codehilite"><pre><span class="nd">@Inject</span>
+<span class="kd">private</span> <span class="n">EntityManager</span>
<span class="n">entityManager</span><span class="o">;</span>
+</pre></div>
+
+
+<p>As you see the usage is the same. You <strong>don't</strong> have to
use <code>ExtendedEntityManager</code> at the injection point. It's just needed
in the producer-method:</p>
+<p>Producer for the default Extended-<code>EntityManager</code> (no EE-Server):</p>
+<div class="codehilite"><pre><span class="c1">//...</span>
+<span class="kd">public</span> <span class="kd">class</span> <span
class="nc">ExtendedEntityManagerProducer</span>
+<span class="o">{</span>
+    <span class="c1">//or manual bootstrapping</span>
+    <span class="nd">@PersistenceContext</span>
+    <span class="kd">private</span> <span class="n">EntityManager</span>
<span class="n">entityManager</span><span class="o">;</span>
+
+    <span class="nd">@Produces</span>
+    <span class="nd">@RequestScoped</span>
+    <span class="kd">protected</span> <span class="n">ExtendedEntityManager</span>
<span class="nf">createEntityManager</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="k">new</span>
<span class="nf">ExtendedEntityManager</span><span class="o">(</span><span
class="k">this</span><span class="o">.</span><span class="na">entityManager</span><span
class="o">);</span>
+    <span class="o">}</span>
+
+    <span class="kd">protected</span> <span class="kt">void</span>
<span class="nf">closeEntityManager</span><span class="o">(</span><span
class="nd">@Disposes</span> <span class="n">ExtendedEntityManager</span>
<span class="n">entityManager</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">if</span> <span class="o">(</span><span
class="n">entityManager</span><span class="o">.</span><span class="na">isOpen</span><span
class="o">())</span>
+        <span class="o">{</span>
+            <span class="n">entityManager</span><span class="o">.</span><span
class="na">close</span><span class="o">();</span>
+        <span class="o">}</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Producer for the default Extended-<code>EntityManager</code> (EE-Server):</p>
+<div class="codehilite"><pre><span class="nd">@ApplicationScoped</span>
+<span class="kd">public</span> <span class="kd">class</span> <span
class="nc">ExtendedEntityManagerProducer</span>
+<span class="o">{</span>
+    <span class="nd">@PersistenceUnit</span>
+    <span class="kd">private</span> <span class="n">EntityManagerFactory</span>
<span class="n">entityManagerFactory</span><span class="o">;</span>
+
+    <span class="nd">@Produces</span>
+    <span class="nd">@Default</span>
+    <span class="nd">@RequestScoped</span>
+    <span class="kd">public</span> <span class="n">ExtendedEntityManager</span>
<span class="nf">create</span><span class="o">()</span>
+    <span class="o">{</span>
+        <span class="k">return</span> <span class="k">new</span>
<span class="nf">ExtendedEntityManager</span><span class="o">(</span><span
class="k">this</span><span class="o">.</span><span class="na">entityManagerFactory</span><span
class="o">.</span><span class="na">createEntityManager</span><span
class="o">());</span>
+    <span class="o">}</span>
+
+    <span class="kd">public</span> <span class="kt">void</span> <span
class="nf">dispose</span><span class="o">(</span><span class="nd">@Disposes</span>
<span class="nd">@Default</span> <span class="n">ExtendedEntityManager</span>
<span class="n">entityManager</span><span class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">if</span> <span class="o">(</span><span
class="n">entityManager</span><span class="o">.</span><span class="na">isOpen</span><span
class="o">())</span>
+        <span class="o">{</span>
+            <span class="n">entityManager</span><span class="o">.</span><span
class="na">close</span><span class="o">();</span>
+        <span class="o">}</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>Implementation of a simple <code>ExtendedEntityManager</code>:</p>
+<div class="codehilite"><pre><span class="nd">@Typed</span><span
class="o">()</span>
+<span class="kd">public</span> <span class="kd">class</span> <span
class="nc">ExtendedEntityManager</span> <span class="kd">implements</span>
<span class="n">EntityManager</span><span class="o">,</span> <span
class="n">Serializable</span>
+<span class="o">{</span>
+    <span class="kd">private</span> <span class="kd">static</span>
<span class="kd">final</span> <span class="kt">long</span> <span
class="n">serialVersionUID</span> <span class="o">=</span> <span class="mi">3770954229283539616L</span><span
class="o">;</span>
+
+    <span class="kd">private</span> <span class="kd">transient</span>
<span class="n">EntityManager</span> <span class="n">wrapped</span><span
class="o">;</span>
+
+    <span class="kd">protected</span> <span class="nf">ExtendedEntityManager</span><span
class="o">()</span>
+    <span class="o">{</span>
+    <span class="o">}</span>
+
+    <span class="kd">public</span> <span class="nf">ExtendedEntityManager</span><span
class="o">(</span><span class="n">EntityManager</span> <span class="n">wrapped</span><span
class="o">)</span>
+    <span class="o">{</span>
+        <span class="k">this</span><span class="o">.</span><span
class="na">wrapped</span> <span class="o">=</span> <span class="n">wrapped</span><span
class="o">;</span>
+    <span class="o">}</span>
+
+    <span class="cm">/*</span>
+<span class="cm">     * generated</span>
+<span class="cm">     */</span>
+    <span class="c1">//delegate all calls to this.wrapped - most IDEs allow to generate
it</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>This approach just works if it <strong>doesn't come to serialization</strong>
of this wrapper e.g. in case of session-replication.
+If those beans get serialized, you have to overcome this restriction by storing the persistence-unit-name
and recreate the <code>EntityManager</code> via <code>Persistence.createEntityManagerFactory(this.persistenceUnitName).createEntityManager();</code>
and sync it with the database before closing it on serialization.
+Furthermore, you have to intercept some methods of the <code>EntityManager</code>
to merge detached entities automatically if those entities get serialized as well. However,
as mentioned before <strong>we don't recommend</strong> such an approach.</p>
 <h1 id="jta-support">JTA Support</h1>
 <p>Per default the transaction-type used by <code>@Transactional</code>is
'RESOURCE_LOCAL'. If you configure <code>transaction-type="JTA"</code>in the persistence.xml,
you have to enable an alternative <code>TransactionStrategy</code> in the beans.xml
which is called <code>org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy</code>.</p>
 <div class="codehilite"><pre><span class="nt">&lt;beans&gt;</span>



Mime
View raw message