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>


Reply via email to