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"><beans></span>