Modified: deltaspike/site/trunk/content/documentation/jpa.html URL: http://svn.apache.org/viewvc/deltaspike/site/trunk/content/documentation/jpa.html?rev=1756698&r1=1756697&r2=1756698&view=diff ============================================================================== --- deltaspike/site/trunk/content/documentation/jpa.html (original) +++ deltaspike/site/trunk/content/documentation/jpa.html Thu Aug 18 00:36:56 2016 @@ -1,989 +1,989 @@ -<!DOCTYPE html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <meta name="description" content="deltaspike-generate-pages"> - <meta name="author" content="chm"> - <!-- No caching headers --> - <meta http-equiv="cache-control" content="no-cache"/> - <meta http-equiv="pragma" content="no-cache"/> - <meta http-equiv="expires" content="-1"/> - - <title>JPA Module</title> - - <!-- - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. - --> - - <!-- Styles --> - <link href="https://deltaspike.apache.org/resources/css/bootstrap.css" rel="stylesheet"> - <link href="https://deltaspike.apache.org/resources/css/bootstrap-responsive.css" rel="stylesheet"> - <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/3.1.0/css/font-awesome.min.css" rel="stylesheet"> - - - - - <!-- Tocify - nice dynamic autoscrolling TOC --> - <link href="https://cdnjs.cloudflare.com/ajax/libs/jquery.tocify/1.9.0/stylesheets/jquery.tocify.min.css" rel="stylesheet"> - <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> - <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script> - <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tocify/1.9.0/javascripts/jquery.tocify.min.js"></script> - - - <script type="text/javascript"> - $(function () { - $("#toc").tocify({ - scrollTo: 50, - extendPage: true, - context: "#doc-content", - selectors: "h2,h3,h4,h5" - }); - $(".fallback-toc").hide(); - }); - </script> - - - <style type="text/css"> - /* Stylesheet for CodeRay to match GitHub theme | MIT License | http://foundation.zurb.com */ -/*pre.CodeRay {background-color:#f7f7f8;}*/ -.CodeRay .line-numbers{border-right:1px solid #d8d8d8;padding:0 0.5em 0 .25em} -.CodeRay span.line-numbers{display:inline-block;margin-right:.5em;color:rgba(0,0,0,.3)} -.CodeRay .line-numbers strong{font-weight: normal} -table.CodeRay{border-collapse:separate;border-spacing:0;margin-bottom:0;border:0;background:none} -table.CodeRay td{vertical-align: top} -table.CodeRay td.line-numbers{text-align:right} -table.CodeRay td.line-numbers>pre{padding:0;color:rgba(0,0,0,.3)} -table.CodeRay td.code{padding:0 0 0 .5em} -table.CodeRay td.code>pre{padding:0} -.CodeRay .debug{color:#fff !important;background:#000080 !important} -.CodeRay .annotation{color:#007} -.CodeRay .attribute-name{color:#000080} -.CodeRay .attribute-value{color:#700} -.CodeRay .binary{color:#509} -.CodeRay .comment{color:#998;font-style:italic} -.CodeRay .char{color:#04d} -.CodeRay .char .content{color:#04d} -.CodeRay .char .delimiter{color:#039} -.CodeRay .class{color:#458;font-weight:bold} -.CodeRay .complex{color:#a08} -.CodeRay .constant,.CodeRay .predefined-constant{color:#008080} -.CodeRay .color{color:#099} -.CodeRay .class-variable{color:#369} -.CodeRay .decorator{color:#b0b} -.CodeRay .definition{color:#099} -.CodeRay .delimiter{color:#000} -.CodeRay .doc{color:#970} -.CodeRay .doctype{color:#34b} -.CodeRay .doc-string{color:#d42} -.CodeRay .escape{color:#666} -.CodeRay .entity{color:#800} -.CodeRay .error{color:#808} -.CodeRay .exception{color:inherit} -.CodeRay .filename{color:#099} -.CodeRay .function{color:#900;font-weight:bold} -.CodeRay .global-variable{color:#008080} -.CodeRay .hex{color:#058} -.CodeRay .integer,.CodeRay .float{color:#099} -.CodeRay .include{color:#555} -.CodeRay .inline{color:#00} -.CodeRay .inline .inline{background:#ccc} -.CodeRay .inline .inline .inline{background:#bbb} -.CodeRay .inline .inline-delimiter{color:#d14} -.CodeRay .inline-delimiter{color:#d14} -.CodeRay .important{color:#555;font-weight:bold} -.CodeRay .interpreted{color:#b2b} -.CodeRay .instance-variable{color:#008080} -.CodeRay .label{color:#970} -.CodeRay .local-variable{color:#963} -.CodeRay .octal{color:#40e} -.CodeRay .predefined{color:#369} -.CodeRay .preprocessor{color:#579} -.CodeRay .pseudo-class{color:#555} -.CodeRay .directive{font-weight:bold} -.CodeRay .type{font-weight:bold} -.CodeRay .predefined-type{color:inherit} -.CodeRay .reserved,.CodeRay .keyword {color:#000;font-weight:bold} -.CodeRay .key{color:#808} -.CodeRay .key .delimiter{color:#606} -.CodeRay .key .char{color:#80f} -.CodeRay .value{color:#088} -.CodeRay .regexp .delimiter{color:#808} -.CodeRay .regexp .content{color:#808} -.CodeRay .regexp .modifier{color:#808} -.CodeRay .regexp .char{color:#d14} -.CodeRay .regexp .function{color:#404;font-weight:bold} -.CodeRay .string{color:#d20} -.CodeRay .string .string .string{background:#ffd0d0} -.CodeRay .string .content{color:#d14} -.CodeRay .string .char{color:#d14} -.CodeRay .string .delimiter{color:#d14} -.CodeRay .shell{color:#d14} -.CodeRay .shell .delimiter{color:#d14} -.CodeRay .symbol{color:#990073} -.CodeRay .symbol .content{color:#a60} -.CodeRay .symbol .delimiter{color:#630} -.CodeRay .tag{color:#008080} -.CodeRay .tag-special{color:#d70} -.CodeRay .variable{color:#036} -.CodeRay .insert{background:#afa} -.CodeRay .delete{background:#faa} -.CodeRay .change{color:#aaf;background:#007} -.CodeRay .head{color:#f8f;background:#505} -.CodeRay .insert .insert{color:#080} -.CodeRay .delete .delete{color:#800} -.CodeRay .change .change{color:#66f} -.CodeRay .head .head{color:#f4f} - - body { - padding-top: 60px; - padding-bottom: 40px; - } - - .toc-like { - border-radius: 6px; - border: 1px solid #ccc; - } - - .toc-like li { - line-height: 30px; - text-indent: 10px; - } - - .toc-like li.custom-toc-header { - font-weight: bold; - background: #666; - color: white; - cursor: initial !important; - padding: 5px; - } - - .toc-like li.custom-toc-header a { - color: white; - font-style: normal; - text-shadow: none; - padding: 0; - } - - .toc-like li.custom-toc-header:hover a { - background: #666; - } - - .page-title { - text-align: left; - } - - #doc-content h2, - #doc-content h3, - #doc-content h4, - #doc-content h5, - #doc-content h6 { - padding-top: 0; - margin-top: 25px; - margin-bottom: 10px; - line-height: 1.4em; - } - - #doc-content h2 { - border-bottom: 1px solid lightgrey; - } - - - </style> - - <script type="text/javascript"> - - var _gaq = _gaq || []; - _gaq.push(['_setAccount', 'UA-36103647-1']); - _gaq.push(['_trackPageview']); - - (function () { - var ga = document.createElement('script'); - ga.type = 'text/javascript'; - ga.async = true; - ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; - var s = document.getElementsByTagName('script')[0]; - s.parentNode.insertBefore(ga, s); - })(); - - </script> -</head> - -<body> - -<div class="navbar navbar-fixed-top"> - <div class="navbar-inner"> - <div class="container"> - <a class="btn btn-navbar" data-toggle="collapse" - data-target=".nav-collapse"> <span class="icon-bar"></span> <span - class="icon-bar"></span> <span class="icon-bar"></span> - </a> - <a class="brand logocolor" href="../index.html">Apache DeltaSpike</a> - - <div class="nav-collapse"> - - - <ul class="nav"> - <li><a href="../index.html">Home</a></li> - <li class="active"><a href="../documentation">Documentation</a></li> - <li ><a href="../javadoc.html">Javadoc</a></li> - <li ><a href="../source.html">Source</a></li> - <li ><a href="../download.html">Download</a></li> - <li ><a href="../community.html">Community</a></li> - <!-- <li><a href="./support.html">Support</a></li> --> - <li ><a href="../news.html">News</a></li> - </ul> - </div> - <!--/.nav-collapse --> - <form id="search-form" action="https://www.google.com/search" - method="get" class="navbar-search pull-right"> - <input value="deltaspike.apache.org" name="sitesearch" - type="hidden"> <input class="search-query" name="q" - id="query" type="text"> - </form> - </div> - </div> -</div> - -<div class="container"> - <div class="row-fluid"> - - - - <div class="span8"> - <div class="page-title"> - <h1>JPA Module</h1> - </div> - - <div id="doc-content"> - <div class="sect1"> -<h2 id="_overview">Overview</h2> -<div class="sectionbody"> -<div class="paragraph"> -<p>The JPA module provides a transactional context and scope, enabling execution of methods within transactions.</p> -</div> -</div> -</div> -<div class="sect1"> -<h2 id="_project_setup">Project Setup</h2> -<div class="sectionbody"> -<div class="paragraph"> -<p>The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <a href="configure.html">Configure DeltaSpike in Your Projects</a>. For Maven-independent projects, see <a href="configure.html#config-maven-indep">Configure DeltaSpike in Maven-independent Projects</a>.</p> -</div> -<div class="sect2"> -<h3 id="_1_declare_jpa_module_dependencies">1. Declare JPA Module Dependencies</h3> -<div class="paragraph"> -<p>Add the JPA module to the list of dependencies in the project <code>pom.xml</code> file using this code snippet:</p> -</div> -<div class="listingblock"> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag"><dependency></span> - <span class="tag"><groupId></span>org.apache.deltaspike.modules<span class="tag"></groupId></span> - <span class="tag"><artifactId></span>deltaspike-jpa-module-api<span class="tag"></artifactId></span> - <span class="tag"><version></span>${deltaspike.version}<span class="tag"></version></span> - <span class="tag"><scope></span>compile<span class="tag"></scope></span> -<span class="tag"></dependency></span> - -<span class="tag"><dependency></span> - <span class="tag"><groupId></span>org.apache.deltaspike.modules<span class="tag"></groupId></span> - <span class="tag"><artifactId></span>deltaspike-jpa-module-impl<span class="tag"></artifactId></span> - <span class="tag"><version></span>${deltaspike.version}<span class="tag"></version></span> - <span class="tag"><scope></span>runtime<span class="tag"></scope></span> -<span class="tag"></dependency></span></code></pre> -</div> -</div> -<div class="paragraph"> -<p>Or if you’re using Gradle, add these dependencies to your <code>build.gradle</code>:</p> -</div> -<div class="listingblock"> -<div class="content"> -<pre class="CodeRay highlight"><code> runtime 'org.apache.deltaspike.modules:deltaspike-jpa-module-impl' - compile 'org.apache.deltaspike.modules:deltaspike-jpa-module-api'</code></pre> -</div> -</div> -</div> -<div class="sect2"> -<h3 id="_2_optional_enable_the_transaction_interceptor">2. (Optional) Enable the Transaction Interceptor</h3> -<div class="admonitionblock note"> -<table> -<tr> -<td class="icon"> -<i class="fa icon-note" title="Note"></i> -</td> -<td class="content"> -If you are using CDI 1.0 or CDI 1.1+ with DeltaSpike v1.1.0 and earlier, you must enable the transaction interceptor in the project <code>beans.xml</code> file: -</td> -</tr> -</table> -</div> -<div class="listingblock"> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag"><beans></span> - <span class="comment"><!-- Not needed with CDI 1.1+ and DeltaSpike v1.1.1+ --></span> - <span class="tag"><interceptors></span> - <span class="tag"><class></span>org.apache.deltaspike.jpa.impl.transaction.TransactionalInterceptor<span class="tag"></class></span> - <span class="tag"></interceptors></span> -<span class="tag"></beans></span></code></pre> -</div> -</div> -</div> -</div> -</div> -<div class="sect1"> -<h2 id="__transactional">@Transactional</h2> -<div class="sectionbody"> -<div class="paragraph"> -<p>This annotation is an alternative to transactional EJBs and enables the execution -of a method within a transaction. Before it is possible to start -using the annotation, it is required to implement a CDI producer for an -<code>EntityManager</code> and it is needed to inject the <code>EntityManager</code> in the -bean which uses <code>@Transactional</code>. As shown later on, it is also possible -to use multiple qualifiers for using different EntityManagers.</p> -</div> -<div class="sect2"> -<h3 id="_basic_usage">Basic usage</h3> -<div class="paragraph"> -<p>The following example shows a simple producer for an <code>EntityManager</code> and -the corresponding disposer method. Producing it as request scoped bean -means that the disposer method will be called on finishing the request. -Alternatively it is possible to use a special scope called -<a href="#__transactionscoped"><code>@TransactionScoped</code></a>.</p> -</div> -<div class="listingblock"> -<div class="title">Producer for the Default EntityManager (non-EE server)</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="comment">//...</span> -<span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> -{ - <span class="comment">//or manual bootstrapping</span> - <span class="annotation">@PersistenceContext</span> - <span class="directive">private</span> EntityManager entityManager; - - <span class="annotation">@Produces</span> - <span class="annotation">@RequestScoped</span> - <span class="directive">protected</span> EntityManager createEntityManager() - { - <span class="keyword">return</span> <span class="local-variable">this</span>.entityManager; - } - - <span class="directive">protected</span> <span class="type">void</span> closeEntityManager(<span class="annotation">@Disposes</span> EntityManager entityManager) - { - <span class="keyword">if</span> (entityManager.isOpen()) - { - entityManager.close(); - } - } -}</code></pre> -</div> -</div> -<div class="listingblock"> -<div class="title">Producer for the Default EntityManager (EE server)</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@ApplicationScoped</span> -<span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> -{ - <span class="annotation">@PersistenceUnit</span> - <span class="directive">private</span> EntityManagerFactory entityManagerFactory; - - <span class="annotation">@Produces</span> - <span class="annotation">@Default</span> - <span class="annotation">@RequestScoped</span> - <span class="directive">public</span> EntityManager create() - { - <span class="keyword">return</span> <span class="local-variable">this</span>.entityManagerFactory.createEntityManager(); - } - - <span class="directive">public</span> <span class="type">void</span> dispose(<span class="annotation">@Disposes</span> <span class="annotation">@Default</span> EntityManager entityManager) - { - <span class="keyword">if</span> (entityManager.isOpen()) - { - entityManager.close(); - } - } -}</code></pre> -</div> -</div> -<div class="paragraph"> -<p>The following examples show how to use the <code>EntityManager</code> produced by -the example above.</p> -</div> -<div class="listingblock"> -<div class="title">Bean with a Transactional Method</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="comment">//...</span> -<span class="directive">public</span> <span class="type">class</span> <span class="class">TransactionalBean</span> -{ - <span class="annotation">@Inject</span> - <span class="directive">private</span> EntityManager entityManager; - - <span class="annotation">@Transactional</span> - <span class="directive">public</span> <span class="type">void</span> executeInTransaction() - { - <span class="comment">//...</span> - } -}</code></pre> -</div> -</div> -<div class="listingblock"> -<div class="title">Simple Transactional Bean (All Methods are Transactional)</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="comment">//...</span> -<span class="annotation">@Transactional</span> -<span class="directive">public</span> <span class="type">class</span> <span class="class">TransactionalBean</span> -{ - <span class="annotation">@Inject</span> - <span class="directive">private</span> EntityManager entityManager; - - <span class="comment">//...</span> -}</code></pre> -</div> -</div> -<div class="paragraph"> -<p>As illustrated in the following example it is also possible to use -<code>@Transactional</code> for stereotypes.</p> -</div> -<div class="listingblock"> -<div class="title">Stereotype for Transactional Beans (+ Usage)</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Stereotype</span> -<span class="annotation">@Transactional</span> -<span class="annotation">@ApplicationScoped</span> -<span class="directive">public</span> <span class="annotation">@interface</span> Repository -{ -} - -<span class="comment">//...</span> -<span class="annotation">@Repository</span> -<span class="directive">public</span> <span class="type">class</span> <span class="class">TransactionalBean</span> -{ - <span class="annotation">@Inject</span> - <span class="directive">private</span> EntityManager entityManager; - - <span class="comment">//...</span> -}</code></pre> -</div> -</div> -</div> -<div class="sect2"> -<h3 id="_multiple_entitymanagers">Multiple EntityManagers</h3> -<div class="paragraph"> -<p>The default qualifier for <code>@Transactional</code> is <code>@Any</code> whereby a transaction gets started for every injected entity manager. Besides such simple usages, it is also possible to access multiple persistence units in parallel using qualifiers.</p> -</div> -<div class="paragraph"> -<p>First, the EntityManagers or EntityManagerFactories must be obtained from the JPA subsystem, then EntityManagers must be made available as CDI beans and finally injected into <code>@Transactional</code> beans for usage.</p> -</div> -<div class="sect3"> -<h4 id="_obtaining_entitymanagers_from_jpa">Obtaining EntityManagers from JPA</h4> -<div class="paragraph"> -<p>In EE managed environments the EntityManager can be obtained directly or through an EntityManagerFactory using standard JPA annotations <code>@PersistenceContext</code> for an EntityManager or <code>@PersistenceUnit</code> for an EntityManagerFactory.</p> -</div> -<div class="listingblock"> -<div class="title">JPA Managed EntityManager</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> { - - <span class="annotation">@PersistenceContext</span>(unitName = <span class="string"><span class="delimiter">"</span><span class="content">firstDB</span><span class="delimiter">"</span></span>) - <span class="directive">private</span> EntityManager firstEntityManager; - - <span class="annotation">@PersistenceContext</span>(unitName = <span class="string"><span class="delimiter">"</span><span class="content">secondDB</span><span class="delimiter">"</span></span>) - <span class="directive">private</span> EntityManager secondEntityManager; - - <span class="comment">// ...</span> -}</code></pre> -</div> -</div> -<div class="paragraph"> -<p>An alternative for non-EE environments is available through DeltaSpike’s <code>@PersistenceUnitName</code> qualifier allowing to inject EntityManagerFactories.</p> -</div> -<div class="listingblock"> -<div class="title">Unmanaged EntityManagerFactory</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> { - - <span class="annotation">@Inject</span> - <span class="annotation">@PersistenceUnitName</span>(<span class="string"><span class="delimiter">"</span><span class="content">puA</span><span class="delimiter">"</span></span>) - <span class="directive">private</span> EntityManagerFactory emfA; - - <span class="annotation">@Inject</span> - <span class="annotation">@PersistenceUnitName</span>(<span class="string"><span class="delimiter">"</span><span class="content">puB</span><span class="delimiter">"</span></span>) - <span class="directive">private</span> EntityManagerFactory emfB; - - <span class="comment">// ...</span> -}</code></pre> -</div> -</div> -<div class="paragraph"> -<p>Obtaining an EntityManager from an EntityManagerFactory is just a matter of calling <code>emfA.createEntityManager()</code>. -DeltaSpike provides a built-in producer for <code>@PersistenceUnitName</code> qualified EntityManagerFactories. -This producer also looks up a property files with the name <code>persistence-{persistenceunit name}.properties</code> via the DeltaSpike <code>PropertyLoader</code>. -For the example above this would be <code>persistence-puA.properties</code>. -The properties in this file will be passed 1:1 to <code>Persistence#createEntityManagerFactory(properties)</code> by the built-in producer method.</p> -</div> -</div> -<div class="sect3"> -<h4 id="_producing_multiple_entitymanagers">Producing Multiple EntityManagers</h4> -<div class="paragraph"> -<p>There are several ways to make multiple entity managers available for use in <code>@Transactional</code> methods, each suitable for a different situation.</p> -</div> -<div class="paragraph"> -<p>The simplest method employs a producer and a disposer for each EntityManager.</p> -</div> -<div class="listingblock"> -<div class="title">Deciding using qualifiers</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> { - - <span class="comment">// ...entity managers or factories injected here</span> - - <span class="annotation">@Produces</span> - <span class="annotation">@RequestScoped</span> <span class="comment">// or other</span> - <span class="annotation">@DbA</span> <span class="comment">//custom qualifier annotation</span> - <span class="directive">public</span> EntityManager createEntityManagerA() - { - <span class="keyword">return</span> emfA.createEntityManager(); - } - - <span class="directive">public</span> <span class="type">void</span> closeEmA(<span class="annotation">@Disposes</span> <span class="annotation">@DbA</span> EntityManager em) - { - em.close(); - } - - <span class="annotation">@Produces</span> - <span class="annotation">@RequestScoped</span> - <span class="annotation">@DbB</span> <span class="comment">//custom qualifier annotation</span> - <span class="directive">public</span> EntityManager createEntityManagerB() - { - <span class="keyword">return</span> emfB.createEntityManager(); - } - - <span class="directive">public</span> <span class="type">void</span> closeEmB(<span class="annotation">@Disposes</span> <span class="annotation">@DbB</span> EntityManager em) - { - em.close(); - } - -}</code></pre> -</div> -</div> -<div class="paragraph"> -<p>If there’s the need to decide dynamically on which EntityManager should be used when it’s possible to use the standard CDI facility of <code>InjectionPoint</code> to get information about the injection points and produce different EntityManagers with just one producer method.</p> -</div> -<div class="listingblock"> -<div class="title">Deciding using InjectionPoint</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> { - - <span class="comment">// ...entity managers or factories injected here</span> - - <span class="annotation">@Produces</span> - <span class="directive">protected</span> EntityManager createEntityManager(InjectionPoint injectionPoint) - { - CustomQualifier customQualifier = injectionPoint.getAnnotated().getAnnotation(CustomQualifier.class); - <span class="keyword">return</span> selectEntityManager(customQualifier); <span class="comment">//selects firstEntityManager or secondEntityManager based on the details provided by CustomQualifier</span> - } -}</code></pre> -</div> -</div> -<div class="paragraph"> -<p>The information necessary to make the decision about the EntityManager appropriate for the current situation and injection point may be available elsewhere, for example in a custom context.</p> -</div> -<div class="listingblock"> -<div class="title">Deciding using anything else</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> { - - <span class="comment">// ...entity managers or factories injected here</span> - - <span class="annotation">@Inject</span> - <span class="directive">private</span> CustomDatabaseContext customDatabaseContext; - - <span class="annotation">@Produces</span> - <span class="directive">protected</span> EntityManager createEntityManager() - { - <span class="keyword">if</span> (customDatabaseContext.usePrimaryDb()) { - <span class="keyword">return</span> firstEntityManager; - } - <span class="keyword">return</span> secondEntityManager; - } -}</code></pre> -</div> -</div> -</div> -<div class="sect3"> -<h4 id="_using_transactions_with_multiple_entitymanagers">Using transactions with multiple EntityManagers</h4> -<div class="paragraph"> -<p>One use case for multiple EntityManagers is their usage in nested transactions. When a transactional method is called from within a transactional method, it joins the existing transaction.</p> -</div> -<div class="listingblock"> -<div class="title">Nested transactions with multiple EntityManagers</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">FirstLevelTransactionBean</span> -{ - <span class="annotation">@Inject</span> - <span class="directive">private</span> <span class="annotation">@First</span> EntityManager firstEntityManager; - - <span class="annotation">@Inject</span> - <span class="directive">private</span> NestedTransactionBean nestedTransactionBean; - - <span class="annotation">@Transactional</span> - <span class="directive">public</span> <span class="type">void</span> executeInTransaction() - { - <span class="comment">//...</span> - <span class="local-variable">this</span>.nestedTransactionBean.executeInTransaction(); - } -} - -<span class="directive">public</span> <span class="type">class</span> <span class="class">NestedTransactionBean</span> -{ - <span class="annotation">@Inject</span> - <span class="directive">private</span> <span class="annotation">@Second</span> EntityManager secondEntityManager; - - <span class="annotation">@Transactional</span> - <span class="directive">public</span> <span class="type">void</span> executeInTransaction() - { - <span class="comment">//...</span> - } -}</code></pre> -</div> -</div> -<div class="paragraph"> -<p>It’s also easy to use multiple EntityManagers in the same bean in different transactional methods. By default, a <code>@Transactional</code> method would enroll all of the EntityManagers in the transaction. By using <code>@Transactional(qualifier=…​)</code> it’s easy to choose individual EntityManagers for each transactional method.</p> -</div> -<div class="listingblock"> -<div class="title">Selecting individual EntityManagers for a transactional method</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">MultiTransactionBean</span> -{ - <span class="annotation">@Inject</span> - <span class="directive">private</span> EntityManager defaultEntityManager; - - <span class="annotation">@Inject</span> - <span class="directive">private</span> <span class="annotation">@First</span> EntityManager firstEntityManager; - - <span class="annotation">@Inject</span> - <span class="directive">private</span> <span class="annotation">@Second</span> EntityManager secondEntityManager; - - <span class="annotation">@Transactional</span>(qualifier = Default.class) - <span class="directive">public</span> <span class="type">void</span> executeInDefaultTransaction() {...} - - <span class="annotation">@Transactional</span>(qualifier = First.class) - <span class="directive">public</span> <span class="type">void</span> executeInFirstTransaction() {...} - - <span class="annotation">@Transactional</span>(qualifier = {First.class, Second.class}) - <span class="directive">public</span> <span class="type">void</span> executeInFirstAndSecondTransaction() {...} -}</code></pre> -</div> -</div> -<div class="paragraph"> -<p>The final transaction handling for all <code>EntityManager</code> s is also done -after the outermost transactional method if <code>NestedTransactionBean</code> uses -a different <code>EntityManager</code>. So it is possible to catch an exception in -<code>FirstLevelTransactionBean</code>, for example, to try an optional path instead of an -immediate rollback.</p> -</div> -</div> -</div> -</div> -</div> -<div class="sect1"> -<h2 id="__transactionscoped">@TransactionScoped</h2> -<div class="sectionbody"> -<div class="paragraph"> -<p><code>@Transactional</code> also starts a context which is available as long as the -transaction started by <code>@Transactional</code>. Besides other beans you can use -this scope for the <code>EntityManager</code> itself. That means the -<code>EntityManager</code> will be closed after leaving the method annotated with -<code>@Transactional</code>.</p> -</div> -<div class="listingblock"> -<div class="title">Using a transaction-scoped EntityManager</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> -{ - <span class="comment">//or manual bootstrapping</span> - <span class="annotation">@PersistenceContext</span> - <span class="directive">private</span> EntityManager entityManager; - - <span class="annotation">@Produces</span> - <span class="annotation">@TransactionScoped</span> - <span class="directive">protected</span> EntityManager createEntityManager() - { - <span class="keyword">return</span> <span class="local-variable">this</span>.entityManager; - } - - <span class="directive">protected</span> <span class="type">void</span> closeEntityManager(<span class="annotation">@Disposes</span> EntityManager entityManager) - { - <span class="keyword">if</span> (entityManager.isOpen()) - { - entityManager.close(); - } - } -}</code></pre> -</div> -</div> -</div> -</div> -<div class="sect1"> -<h2 id="_extended_persistence_contexts">Extended Persistence Contexts</h2> -<div class="sectionbody"> -<div class="paragraph"> -<p>Frameworks like MyFaces Orchestra provide a feature which allows keeping -an <code>EntityManager</code> across multiple requests. That means it is not -required to call <code>EntityManager#merge</code> to add detached entities to the -context. However, several application architectures do not 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 -especially if an application does not 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> is not serializable. Beans which are scoped in a -normal-scoped CDI context have to be serializable. So by default it -is not allowed by CDI to provide a producer-method which exposes, for example, a -conversation scoped <code>EntityManager</code> as it is. We <strong>do not</strong> recommend this approach and therefore it is not available out-of-the-box. -However, if you really need this approach to avoid calling <code>#merge</code> for -your detached entities, it is pretty simple to add this functionality.</p> -</div> -<div class="listingblock"> -<div class="title">Usage of a Simple extended EntityManager</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Inject</span> -<span class="directive">private</span> EntityManager entityManager;</code></pre> -</div> -</div> -<div class="paragraph"> -<p>As you see the usage is the same. You <strong>do not</strong> have to use -<code>ExtendedEntityManager</code> at the injection point. It is just needed in the -producer-method:</p> -</div> -<div class="listingblock"> -<div class="title">Producer for an extended EntityManager (non-EE server)</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="comment">//...</span> -<span class="directive">public</span> <span class="type">class</span> <span class="class">ExtendedEntityManagerProducer</span> -{ - <span class="comment">//or manual bootstrapping</span> - <span class="annotation">@PersistenceContext</span> - <span class="directive">private</span> EntityManager entityManager; - - <span class="annotation">@Produces</span> - <span class="annotation">@RequestScoped</span> - <span class="directive">protected</span> ExtendedEntityManager createEntityManager() - { - <span class="keyword">return</span> <span class="keyword">new</span> ExtendedEntityManager(<span class="local-variable">this</span>.entityManager); - } - - <span class="directive">protected</span> <span class="type">void</span> closeEntityManager(<span class="annotation">@Disposes</span> ExtendedEntityManager entityManager) - { - <span class="keyword">if</span> (entityManager.isOpen()) - { - entityManager.close(); - } - } -}</code></pre> -</div> -</div> -<div class="listingblock"> -<div class="title">Producer for an extended EntityManager (EE server)</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@ApplicationScoped</span> -<span class="directive">public</span> <span class="type">class</span> <span class="class">ExtendedEntityManagerProducer</span> -{ - <span class="annotation">@PersistenceUnit</span> - <span class="directive">private</span> EntityManagerFactory entityManagerFactory; - - <span class="annotation">@Produces</span> - <span class="annotation">@Default</span> - <span class="annotation">@RequestScoped</span> - <span class="directive">public</span> ExtendedEntityManager create() - { - <span class="keyword">return</span> <span class="keyword">new</span> ExtendedEntityManager(<span class="local-variable">this</span>.entityManagerFactory.createEntityManager()); - } - - <span class="directive">public</span> <span class="type">void</span> dispose(<span class="annotation">@Disposes</span> <span class="annotation">@Default</span> ExtendedEntityManager entityManager) - { - <span class="keyword">if</span> (entityManager.isOpen()) - { - entityManager.close(); - } - } -}</code></pre> -</div> -</div> -<div class="listingblock"> -<div class="title">Implementation of a simple extended EntityManager</div> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Typed</span>() -<span class="directive">public</span> <span class="type">class</span> <span class="class">ExtendedEntityManager</span> <span class="directive">implements</span> EntityManager, <span class="predefined-type">Serializable</span> -{ - <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">long</span> serialVersionUID = <span class="integer">3770954229283539616L</span>; - - <span class="directive">private</span> <span class="directive">transient</span> EntityManager wrapped; - - <span class="directive">protected</span> ExtendedEntityManager() - { - } - - <span class="directive">public</span> ExtendedEntityManager(EntityManager wrapped) - { - <span class="local-variable">this</span>.wrapped = wrapped; - } - - <span class="comment">/* - * generated - */</span> - <span class="comment">//delegate all calls to this.wrapped - most IDEs allow to generate it</span> -}</code></pre> -</div> -</div> -<div class="paragraph"> -<p>This approach just works if it <strong>does not come to serialization</strong> of this -wrapper, for example 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 do not recommend</strong> -such an approach.</p> -</div> -</div> -</div> -<div class="sect1"> -<h2 id="_jta_support">JTA Support</h2> -<div class="sectionbody"> -<div class="paragraph"> -<p>By default the transaction-type used by <code>@Transactional</code> is -<code>RESOURCE_LOCAL</code>. If you configure <code>transaction-type="JTA"</code> in the -persistence.xml file, 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> -<div class="listingblock"> -<div class="content"> -<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag"><beans></span> - <span class="tag"><alternatives></span> - <span class="tag"><class></span>org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy<span class="tag"></class></span> - <span class="tag"></alternatives></span> -<span class="tag"></beans></span></code></pre> -</div> -</div> -<div class="paragraph"> -<p>Alternatively, you may expect that your transactions are started at a higher level, e.g. you’re exposing a REST API -and the endpoints themselves are either <code>@Transactional</code> or Stateless session beans, either with container managed -Transactions, you would use <code>org.apache.deltaspike.jpa.impl.transaction.ContainerManagedTransactionStrategy</code>. This -is the strategy to use if you are leveraging <code>@PersistenceContext</code> to inject your <code>EntityManager</code>.</p> -</div> -<div class="paragraph"> -<p>If you have multiple persistence units and you have to use both -transaction types or the settings for development have to be different -than the production settings, you can use -<code>org.apache.deltaspike.jpa.impl.transaction.EnvironmentAwareTransactionStrategy</code> -instead.</p> -</div> -<div class="admonitionblock note"> -<table> -<tr> -<td class="icon"> -<i class="fa icon-note" title="Note"></i> -</td> -<td class="content"> -In case of some versions of Weld - including several versions of JBoss EAP/Wildfly and Websphere Liberty Profile - -or OpenWebBeans in BDA mode - which is not the default one, you have -to configure it as a <a href="spi.html#GlobalAlternative">global alternative</a> instead of an <code>alternative</code> in -<code>beans.xml</code>. That means you have to add, for example, -<code>globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy -=org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy</code> or -<code>globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy = org.apache.deltaspike.jpa.impl.transaction.ContainerManagedTransactionStrategy</code> -to <code>/META-INF/apache-deltaspike.properties</code>. -</td> -</tr> -</table> -</div> -</div> -</div> - </div> - </div> - - - <div class="span4"> - <div id="toc"> - <div class="moduledeps"> - <ul class="toc-like nav nav-list"> - - <li class="custom-toc-header">Depends on</li> - - <li><a href="core.html">Core</a></li> - - - - <li class="custom-toc-header"><a href="core.html#_internal_configuration">Configuration</a></li> - - <li><a href="https://github.com/apache/deltaspike/blob/master/deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/api/transaction/TransactionConfig.java">TransactionConfig</a></li> - - - - <li class="custom-toc-header">Table of Contents</li> - - </ul> - </div> - </div> - - <div class="fallback-toc"> - <ul class="sectlevel1"> -<li><a href="#_overview">Overview</a></li> -<li><a href="#_project_setup">Project Setup</a> -<ul class="sectlevel2"> -<li><a href="#_1_declare_jpa_module_dependencies">1. Declare JPA Module Dependencies</a></li> -<li><a href="#_2_optional_enable_the_transaction_interceptor">2. (Optional) Enable the Transaction Interceptor</a></li> -</ul> -</li> -<li><a href="#__transactional">@Transactional</a> -<ul class="sectlevel2"> -<li><a href="#_basic_usage">Basic usage</a></li> -<li><a href="#_multiple_entitymanagers">Multiple EntityManagers</a> -<ul class="sectlevel3"> -<li><a href="#_obtaining_entitymanagers_from_jpa">Obtaining EntityManagers from JPA</a></li> -<li><a href="#_producing_multiple_entitymanagers">Producing Multiple EntityManagers</a></li> -<li><a href="#_using_transactions_with_multiple_entitymanagers">Using transactions with multiple EntityManagers</a></li> -</ul> -</li> -</ul> -</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> - - </div> - - - </div> - <div class="row"> - <hr> - <footer> - <p>Copyright © 2011-2016 The Apache Software Foundation, - Licensed under the Apache License, Version 2.0.</p> - - <p>Apache and the Apache feather logo are trademarks of The Apache Software Foundation.</p> - </footer> - </div> -</div> - -</body> +<!DOCTYPE html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="deltaspike-generate-pages"> + <meta name="author" content="chm"> + <!-- No caching headers --> + <meta http-equiv="cache-control" content="no-cache"/> + <meta http-equiv="pragma" content="no-cache"/> + <meta http-equiv="expires" content="-1"/> + + <title>JPA Module</title> + + <!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + --> + + <!-- Styles --> + <link href="https://deltaspike.apache.org/resources/css/bootstrap.css" rel="stylesheet"> + <link href="https://deltaspike.apache.org/resources/css/bootstrap-responsive.css" rel="stylesheet"> + <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/3.1.0/css/font-awesome.min.css" rel="stylesheet"> + + + + + <!-- Tocify - nice dynamic autoscrolling TOC --> + <link href="https://cdnjs.cloudflare.com/ajax/libs/jquery.tocify/1.9.0/stylesheets/jquery.tocify.min.css" rel="stylesheet"> + <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tocify/1.9.0/javascripts/jquery.tocify.min.js"></script> + + + <script type="text/javascript"> + $(function () { + $("#toc").tocify({ + scrollTo: 50, + extendPage: true, + context: "#doc-content", + selectors: "h2,h3,h4,h5" + }); + $(".fallback-toc").hide(); + }); + </script> + + + <style type="text/css"> + /* Stylesheet for CodeRay to match GitHub theme | MIT License | http://foundation.zurb.com */ +/*pre.CodeRay {background-color:#f7f7f8;}*/ +.CodeRay .line-numbers{border-right:1px solid #d8d8d8;padding:0 0.5em 0 .25em} +.CodeRay span.line-numbers{display:inline-block;margin-right:.5em;color:rgba(0,0,0,.3)} +.CodeRay .line-numbers strong{font-weight: normal} +table.CodeRay{border-collapse:separate;border-spacing:0;margin-bottom:0;border:0;background:none} +table.CodeRay td{vertical-align: top} +table.CodeRay td.line-numbers{text-align:right} +table.CodeRay td.line-numbers>pre{padding:0;color:rgba(0,0,0,.3)} +table.CodeRay td.code{padding:0 0 0 .5em} +table.CodeRay td.code>pre{padding:0} +.CodeRay .debug{color:#fff !important;background:#000080 !important} +.CodeRay .annotation{color:#007} +.CodeRay .attribute-name{color:#000080} +.CodeRay .attribute-value{color:#700} +.CodeRay .binary{color:#509} +.CodeRay .comment{color:#998;font-style:italic} +.CodeRay .char{color:#04d} +.CodeRay .char .content{color:#04d} +.CodeRay .char .delimiter{color:#039} +.CodeRay .class{color:#458;font-weight:bold} +.CodeRay .complex{color:#a08} +.CodeRay .constant,.CodeRay .predefined-constant{color:#008080} +.CodeRay .color{color:#099} +.CodeRay .class-variable{color:#369} +.CodeRay .decorator{color:#b0b} +.CodeRay .definition{color:#099} +.CodeRay .delimiter{color:#000} +.CodeRay .doc{color:#970} +.CodeRay .doctype{color:#34b} +.CodeRay .doc-string{color:#d42} +.CodeRay .escape{color:#666} +.CodeRay .entity{color:#800} +.CodeRay .error{color:#808} +.CodeRay .exception{color:inherit} +.CodeRay .filename{color:#099} +.CodeRay .function{color:#900;font-weight:bold} +.CodeRay .global-variable{color:#008080} +.CodeRay .hex{color:#058} +.CodeRay .integer,.CodeRay .float{color:#099} +.CodeRay .include{color:#555} +.CodeRay .inline{color:#00} +.CodeRay .inline .inline{background:#ccc} +.CodeRay .inline .inline .inline{background:#bbb} +.CodeRay .inline .inline-delimiter{color:#d14} +.CodeRay .inline-delimiter{color:#d14} +.CodeRay .important{color:#555;font-weight:bold} +.CodeRay .interpreted{color:#b2b} +.CodeRay .instance-variable{color:#008080} +.CodeRay .label{color:#970} +.CodeRay .local-variable{color:#963} +.CodeRay .octal{color:#40e} +.CodeRay .predefined{color:#369} +.CodeRay .preprocessor{color:#579} +.CodeRay .pseudo-class{color:#555} +.CodeRay .directive{font-weight:bold} +.CodeRay .type{font-weight:bold} +.CodeRay .predefined-type{color:inherit} +.CodeRay .reserved,.CodeRay .keyword {color:#000;font-weight:bold} +.CodeRay .key{color:#808} +.CodeRay .key .delimiter{color:#606} +.CodeRay .key .char{color:#80f} +.CodeRay .value{color:#088} +.CodeRay .regexp .delimiter{color:#808} +.CodeRay .regexp .content{color:#808} +.CodeRay .regexp .modifier{color:#808} +.CodeRay .regexp .char{color:#d14} +.CodeRay .regexp .function{color:#404;font-weight:bold} +.CodeRay .string{color:#d20} +.CodeRay .string .string .string{background:#ffd0d0} +.CodeRay .string .content{color:#d14} +.CodeRay .string .char{color:#d14} +.CodeRay .string .delimiter{color:#d14} +.CodeRay .shell{color:#d14} +.CodeRay .shell .delimiter{color:#d14} +.CodeRay .symbol{color:#990073} +.CodeRay .symbol .content{color:#a60} +.CodeRay .symbol .delimiter{color:#630} +.CodeRay .tag{color:#008080} +.CodeRay .tag-special{color:#d70} +.CodeRay .variable{color:#036} +.CodeRay .insert{background:#afa} +.CodeRay .delete{background:#faa} +.CodeRay .change{color:#aaf;background:#007} +.CodeRay .head{color:#f8f;background:#505} +.CodeRay .insert .insert{color:#080} +.CodeRay .delete .delete{color:#800} +.CodeRay .change .change{color:#66f} +.CodeRay .head .head{color:#f4f} + + body { + padding-top: 60px; + padding-bottom: 40px; + } + + .toc-like { + border-radius: 6px; + border: 1px solid #ccc; + } + + .toc-like li { + line-height: 30px; + text-indent: 10px; + } + + .toc-like li.custom-toc-header { + font-weight: bold; + background: #666; + color: white; + cursor: initial !important; + padding: 5px; + } + + .toc-like li.custom-toc-header a { + color: white; + font-style: normal; + text-shadow: none; + padding: 0; + } + + .toc-like li.custom-toc-header:hover a { + background: #666; + } + + .page-title { + text-align: left; + } + + #doc-content h2, + #doc-content h3, + #doc-content h4, + #doc-content h5, + #doc-content h6 { + padding-top: 0; + margin-top: 25px; + margin-bottom: 10px; + line-height: 1.4em; + } + + #doc-content h2 { + border-bottom: 1px solid lightgrey; + } + + + </style> + + <script type="text/javascript"> + + var _gaq = _gaq || []; + _gaq.push(['_setAccount', 'UA-36103647-1']); + _gaq.push(['_trackPageview']); + + (function () { + var ga = document.createElement('script'); + ga.type = 'text/javascript'; + ga.async = true; + ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; + s.parentNode.insertBefore(ga, s); + })(); + + </script> +</head> + +<body> + +<div class="navbar navbar-fixed-top"> + <div class="navbar-inner"> + <div class="container"> + <a class="btn btn-navbar" data-toggle="collapse" + data-target=".nav-collapse"> <span class="icon-bar"></span> <span + class="icon-bar"></span> <span class="icon-bar"></span> + </a> + <a class="brand logocolor" href="../index.html">Apache DeltaSpike</a> + + <div class="nav-collapse"> + + + <ul class="nav"> + <li><a href="../index.html">Home</a></li> + <li class="active"><a href="../documentation">Documentation</a></li> + <li ><a href="../javadoc.html">Javadoc</a></li> + <li ><a href="../source.html">Source</a></li> + <li ><a href="../download.html">Download</a></li> + <li ><a href="../community.html">Community</a></li> + <!-- <li><a href="./support.html">Support</a></li> --> + <li ><a href="../news.html">News</a></li> + </ul> + </div> + <!--/.nav-collapse --> + <form id="search-form" action="https://www.google.com/search" + method="get" class="navbar-search pull-right"> + <input value="deltaspike.apache.org" name="sitesearch" + type="hidden"> <input class="search-query" name="q" + id="query" type="text"> + </form> + </div> + </div> +</div> + +<div class="container"> + <div class="row-fluid"> + + + + <div class="span8"> + <div class="page-title"> + <h1>JPA Module</h1> + </div> + + <div id="doc-content"> + <div class="sect1"> +<h2 id="_overview">Overview</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>The JPA module provides a transactional context and scope, enabling execution of methods within transactions.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_project_setup">Project Setup</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <a href="configure.html">Configure DeltaSpike in Your Projects</a>. For Maven-independent projects, see <a href="configure.html#config-maven-indep">Configure DeltaSpike in Maven-independent Projects</a>.</p> +</div> +<div class="sect2"> +<h3 id="_1_declare_jpa_module_dependencies">1. Declare JPA Module Dependencies</h3> +<div class="paragraph"> +<p>Add the JPA module to the list of dependencies in the project <code>pom.xml</code> file using this code snippet:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag"><dependency></span> + <span class="tag"><groupId></span>org.apache.deltaspike.modules<span class="tag"></groupId></span> + <span class="tag"><artifactId></span>deltaspike-jpa-module-api<span class="tag"></artifactId></span> + <span class="tag"><version></span>${deltaspike.version}<span class="tag"></version></span> + <span class="tag"><scope></span>compile<span class="tag"></scope></span> +<span class="tag"></dependency></span> + +<span class="tag"><dependency></span> + <span class="tag"><groupId></span>org.apache.deltaspike.modules<span class="tag"></groupId></span> + <span class="tag"><artifactId></span>deltaspike-jpa-module-impl<span class="tag"></artifactId></span> + <span class="tag"><version></span>${deltaspike.version}<span class="tag"></version></span> + <span class="tag"><scope></span>runtime<span class="tag"></scope></span> +<span class="tag"></dependency></span></code></pre> +</div> +</div> +<div class="paragraph"> +<p>Or if you’re using Gradle, add these dependencies to your <code>build.gradle</code>:</p> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code> runtime 'org.apache.deltaspike.modules:deltaspike-jpa-module-impl' + compile 'org.apache.deltaspike.modules:deltaspike-jpa-module-api'</code></pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_2_optional_enable_the_transaction_interceptor">2. (Optional) Enable the Transaction Interceptor</h3> +<div class="admonitionblock note"> +<table> +<tr> +<td class="icon"> +<i class="fa icon-note" title="Note"></i> +</td> +<td class="content"> +If you are using CDI 1.0 or CDI 1.1+ with DeltaSpike v1.1.0 and earlier, you must enable the transaction interceptor in the project <code>beans.xml</code> file: +</td> +</tr> +</table> +</div> +<div class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag"><beans></span> + <span class="comment"><!-- Not needed with CDI 1.1+ and DeltaSpike v1.1.1+ --></span> + <span class="tag"><interceptors></span> + <span class="tag"><class></span>org.apache.deltaspike.jpa.impl.transaction.TransactionalInterceptor<span class="tag"></class></span> + <span class="tag"></interceptors></span> +<span class="tag"></beans></span></code></pre> +</div> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="__transactional">@Transactional</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>This annotation is an alternative to transactional EJBs and enables the execution +of a method within a transaction. Before it is possible to start +using the annotation, it is required to implement a CDI producer for an +<code>EntityManager</code> and it is needed to inject the <code>EntityManager</code> in the +bean which uses <code>@Transactional</code>. As shown later on, it is also possible +to use multiple qualifiers for using different EntityManagers.</p> +</div> +<div class="sect2"> +<h3 id="_basic_usage">Basic usage</h3> +<div class="paragraph"> +<p>The following example shows a simple producer for an <code>EntityManager</code> and +the corresponding disposer method. Producing it as request scoped bean +means that the disposer method will be called on finishing the request. +Alternatively it is possible to use a special scope called +<a href="#__transactionscoped"><code>@TransactionScoped</code></a>.</p> +</div> +<div class="listingblock"> +<div class="title">Producer for the Default EntityManager (non-EE server)</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="comment">//...</span> +<span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> +{ + <span class="comment">//or manual bootstrapping</span> + <span class="annotation">@PersistenceContext</span> + <span class="directive">private</span> EntityManager entityManager; + + <span class="annotation">@Produces</span> + <span class="annotation">@RequestScoped</span> + <span class="directive">protected</span> EntityManager createEntityManager() + { + <span class="keyword">return</span> <span class="local-variable">this</span>.entityManager; + } + + <span class="directive">protected</span> <span class="type">void</span> closeEntityManager(<span class="annotation">@Disposes</span> EntityManager entityManager) + { + <span class="keyword">if</span> (entityManager.isOpen()) + { + entityManager.close(); + } + } +}</code></pre> +</div> +</div> +<div class="listingblock"> +<div class="title">Producer for the Default EntityManager (EE server)</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@ApplicationScoped</span> +<span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> +{ + <span class="annotation">@PersistenceUnit</span> + <span class="directive">private</span> EntityManagerFactory entityManagerFactory; + + <span class="annotation">@Produces</span> + <span class="annotation">@Default</span> + <span class="annotation">@RequestScoped</span> + <span class="directive">public</span> EntityManager create() + { + <span class="keyword">return</span> <span class="local-variable">this</span>.entityManagerFactory.createEntityManager(); + } + + <span class="directive">public</span> <span class="type">void</span> dispose(<span class="annotation">@Disposes</span> <span class="annotation">@Default</span> EntityManager entityManager) + { + <span class="keyword">if</span> (entityManager.isOpen()) + { + entityManager.close(); + } + } +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>The following examples show how to use the <code>EntityManager</code> produced by +the example above.</p> +</div> +<div class="listingblock"> +<div class="title">Bean with a Transactional Method</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="comment">//...</span> +<span class="directive">public</span> <span class="type">class</span> <span class="class">TransactionalBean</span> +{ + <span class="annotation">@Inject</span> + <span class="directive">private</span> EntityManager entityManager; + + <span class="annotation">@Transactional</span> + <span class="directive">public</span> <span class="type">void</span> executeInTransaction() + { + <span class="comment">//...</span> + } +}</code></pre> +</div> +</div> +<div class="listingblock"> +<div class="title">Simple Transactional Bean (All Methods are Transactional)</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="comment">//...</span> +<span class="annotation">@Transactional</span> +<span class="directive">public</span> <span class="type">class</span> <span class="class">TransactionalBean</span> +{ + <span class="annotation">@Inject</span> + <span class="directive">private</span> EntityManager entityManager; + + <span class="comment">//...</span> +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>As illustrated in the following example it is also possible to use +<code>@Transactional</code> for stereotypes.</p> +</div> +<div class="listingblock"> +<div class="title">Stereotype for Transactional Beans (+ Usage)</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Stereotype</span> +<span class="annotation">@Transactional</span> +<span class="annotation">@ApplicationScoped</span> +<span class="directive">public</span> <span class="annotation">@interface</span> Repository +{ +} + +<span class="comment">//...</span> +<span class="annotation">@Repository</span> +<span class="directive">public</span> <span class="type">class</span> <span class="class">TransactionalBean</span> +{ + <span class="annotation">@Inject</span> + <span class="directive">private</span> EntityManager entityManager; + + <span class="comment">//...</span> +}</code></pre> +</div> +</div> +</div> +<div class="sect2"> +<h3 id="_multiple_entitymanagers">Multiple EntityManagers</h3> +<div class="paragraph"> +<p>The default qualifier for <code>@Transactional</code> is <code>@Any</code> whereby a transaction gets started for every injected entity manager. Besides such simple usages, it is also possible to access multiple persistence units in parallel using qualifiers.</p> +</div> +<div class="paragraph"> +<p>First, the EntityManagers or EntityManagerFactories must be obtained from the JPA subsystem, then EntityManagers must be made available as CDI beans and finally injected into <code>@Transactional</code> beans for usage.</p> +</div> +<div class="sect3"> +<h4 id="_obtaining_entitymanagers_from_jpa">Obtaining EntityManagers from JPA</h4> +<div class="paragraph"> +<p>In EE managed environments the EntityManager can be obtained directly or through an EntityManagerFactory using standard JPA annotations <code>@PersistenceContext</code> for an EntityManager or <code>@PersistenceUnit</code> for an EntityManagerFactory.</p> +</div> +<div class="listingblock"> +<div class="title">JPA Managed EntityManager</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> { + + <span class="annotation">@PersistenceContext</span>(unitName = <span class="string"><span class="delimiter">"</span><span class="content">firstDB</span><span class="delimiter">"</span></span>) + <span class="directive">private</span> EntityManager firstEntityManager; + + <span class="annotation">@PersistenceContext</span>(unitName = <span class="string"><span class="delimiter">"</span><span class="content">secondDB</span><span class="delimiter">"</span></span>) + <span class="directive">private</span> EntityManager secondEntityManager; + + <span class="comment">// ...</span> +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>An alternative for non-EE environments is available through DeltaSpike’s <code>@PersistenceUnitName</code> qualifier allowing to inject EntityManagerFactories.</p> +</div> +<div class="listingblock"> +<div class="title">Unmanaged EntityManagerFactory</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> { + + <span class="annotation">@Inject</span> + <span class="annotation">@PersistenceUnitName</span>(<span class="string"><span class="delimiter">"</span><span class="content">puA</span><span class="delimiter">"</span></span>) + <span class="directive">private</span> EntityManagerFactory emfA; + + <span class="annotation">@Inject</span> + <span class="annotation">@PersistenceUnitName</span>(<span class="string"><span class="delimiter">"</span><span class="content">puB</span><span class="delimiter">"</span></span>) + <span class="directive">private</span> EntityManagerFactory emfB; + + <span class="comment">// ...</span> +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>Obtaining an EntityManager from an EntityManagerFactory is just a matter of calling <code>emfA.createEntityManager()</code>. +DeltaSpike provides a built-in producer for <code>@PersistenceUnitName</code> qualified EntityManagerFactories. +This producer also looks up a property files with the name <code>persistence-{persistenceunit name}.properties</code> via the DeltaSpike <code>PropertyLoader</code>. +For the example above this would be <code>persistence-puA.properties</code>. +The properties in this file will be passed 1:1 to <code>Persistence#createEntityManagerFactory(properties)</code> by the built-in producer method.</p> +</div> +</div> +<div class="sect3"> +<h4 id="_producing_multiple_entitymanagers">Producing Multiple EntityManagers</h4> +<div class="paragraph"> +<p>There are several ways to make multiple entity managers available for use in <code>@Transactional</code> methods, each suitable for a different situation.</p> +</div> +<div class="paragraph"> +<p>The simplest method employs a producer and a disposer for each EntityManager.</p> +</div> +<div class="listingblock"> +<div class="title">Deciding using qualifiers</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> { + + <span class="comment">// ...entity managers or factories injected here</span> + + <span class="annotation">@Produces</span> + <span class="annotation">@RequestScoped</span> <span class="comment">// or other</span> + <span class="annotation">@DbA</span> <span class="comment">//custom qualifier annotation</span> + <span class="directive">public</span> EntityManager createEntityManagerA() + { + <span class="keyword">return</span> emfA.createEntityManager(); + } + + <span class="directive">public</span> <span class="type">void</span> closeEmA(<span class="annotation">@Disposes</span> <span class="annotation">@DbA</span> EntityManager em) + { + em.close(); + } + + <span class="annotation">@Produces</span> + <span class="annotation">@RequestScoped</span> + <span class="annotation">@DbB</span> <span class="comment">//custom qualifier annotation</span> + <span class="directive">public</span> EntityManager createEntityManagerB() + { + <span class="keyword">return</span> emfB.createEntityManager(); + } + + <span class="directive">public</span> <span class="type">void</span> closeEmB(<span class="annotation">@Disposes</span> <span class="annotation">@DbB</span> EntityManager em) + { + em.close(); + } + +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>If there’s the need to decide dynamically on which EntityManager should be used when it’s possible to use the standard CDI facility of <code>InjectionPoint</code> to get information about the injection points and produce different EntityManagers with just one producer method.</p> +</div> +<div class="listingblock"> +<div class="title">Deciding using InjectionPoint</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> { + + <span class="comment">// ...entity managers or factories injected here</span> + + <span class="annotation">@Produces</span> + <span class="directive">protected</span> EntityManager createEntityManager(InjectionPoint injectionPoint) + { + CustomQualifier customQualifier = injectionPoint.getAnnotated().getAnnotation(CustomQualifier.class); + <span class="keyword">return</span> selectEntityManager(customQualifier); <span class="comment">//selects firstEntityManager or secondEntityManager based on the details provided by CustomQualifier</span> + } +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>The information necessary to make the decision about the EntityManager appropriate for the current situation and injection point may be available elsewhere, for example in a custom context.</p> +</div> +<div class="listingblock"> +<div class="title">Deciding using anything else</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> { + + <span class="comment">// ...entity managers or factories injected here</span> + + <span class="annotation">@Inject</span> + <span class="directive">private</span> CustomDatabaseContext customDatabaseContext; + + <span class="annotation">@Produces</span> + <span class="directive">protected</span> EntityManager createEntityManager() + { + <span class="keyword">if</span> (customDatabaseContext.usePrimaryDb()) { + <span class="keyword">return</span> firstEntityManager; + } + <span class="keyword">return</span> secondEntityManager; + } +}</code></pre> +</div> +</div> +</div> +<div class="sect3"> +<h4 id="_using_transactions_with_multiple_entitymanagers">Using transactions with multiple EntityManagers</h4> +<div class="paragraph"> +<p>One use case for multiple EntityManagers is their usage in nested transactions. When a transactional method is called from within a transactional method, it joins the existing transaction.</p> +</div> +<div class="listingblock"> +<div class="title">Nested transactions with multiple EntityManagers</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">FirstLevelTransactionBean</span> +{ + <span class="annotation">@Inject</span> + <span class="directive">private</span> <span class="annotation">@First</span> EntityManager firstEntityManager; + + <span class="annotation">@Inject</span> + <span class="directive">private</span> NestedTransactionBean nestedTransactionBean; + + <span class="annotation">@Transactional</span> + <span class="directive">public</span> <span class="type">void</span> executeInTransaction() + { + <span class="comment">//...</span> + <span class="local-variable">this</span>.nestedTransactionBean.executeInTransaction(); + } +} + +<span class="directive">public</span> <span class="type">class</span> <span class="class">NestedTransactionBean</span> +{ + <span class="annotation">@Inject</span> + <span class="directive">private</span> <span class="annotation">@Second</span> EntityManager secondEntityManager; + + <span class="annotation">@Transactional</span> + <span class="directive">public</span> <span class="type">void</span> executeInTransaction() + { + <span class="comment">//...</span> + } +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>It’s also easy to use multiple EntityManagers in the same bean in different transactional methods. By default, a <code>@Transactional</code> method would enroll all of the EntityManagers in the transaction. By using <code>@Transactional(qualifier=…​)</code> it’s easy to choose individual EntityManagers for each transactional method.</p> +</div> +<div class="listingblock"> +<div class="title">Selecting individual EntityManagers for a transactional method</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">MultiTransactionBean</span> +{ + <span class="annotation">@Inject</span> + <span class="directive">private</span> EntityManager defaultEntityManager; + + <span class="annotation">@Inject</span> + <span class="directive">private</span> <span class="annotation">@First</span> EntityManager firstEntityManager; + + <span class="annotation">@Inject</span> + <span class="directive">private</span> <span class="annotation">@Second</span> EntityManager secondEntityManager; + + <span class="annotation">@Transactional</span>(qualifier = Default.class) + <span class="directive">public</span> <span class="type">void</span> executeInDefaultTransaction() {...} + + <span class="annotation">@Transactional</span>(qualifier = First.class) + <span class="directive">public</span> <span class="type">void</span> executeInFirstTransaction() {...} + + <span class="annotation">@Transactional</span>(qualifier = {First.class, Second.class}) + <span class="directive">public</span> <span class="type">void</span> executeInFirstAndSecondTransaction() {...} +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>The final transaction handling for all <code>EntityManager</code> s is also done +after the outermost transactional method if <code>NestedTransactionBean</code> uses +a different <code>EntityManager</code>. So it is possible to catch an exception in +<code>FirstLevelTransactionBean</code>, for example, to try an optional path instead of an +immediate rollback.</p> +</div> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="__transactionscoped">@TransactionScoped</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p><code>@Transactional</code> also starts a context which is available as long as the +transaction started by <code>@Transactional</code>. Besides other beans you can use +this scope for the <code>EntityManager</code> itself. That means the +<code>EntityManager</code> will be closed after leaving the method annotated with +<code>@Transactional</code>.</p> +</div> +<div class="listingblock"> +<div class="title">Using a transaction-scoped EntityManager</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">EntityManagerProducer</span> +{ + <span class="comment">//or manual bootstrapping</span> + <span class="annotation">@PersistenceContext</span> + <span class="directive">private</span> EntityManager entityManager; + + <span class="annotation">@Produces</span> + <span class="annotation">@TransactionScoped</span> + <span class="directive">protected</span> EntityManager createEntityManager() + { + <span class="keyword">return</span> <span class="local-variable">this</span>.entityManager; + } + + <span class="directive">protected</span> <span class="type">void</span> closeEntityManager(<span class="annotation">@Disposes</span> EntityManager entityManager) + { + <span class="keyword">if</span> (entityManager.isOpen()) + { + entityManager.close(); + } + } +}</code></pre> +</div> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_extended_persistence_contexts">Extended Persistence Contexts</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>Frameworks like MyFaces Orchestra provide a feature which allows keeping +an <code>EntityManager</code> across multiple requests. That means it is not +required to call <code>EntityManager#merge</code> to add detached entities to the +context. However, several application architectures do not 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 +especially if an application does not 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> is not serializable. Beans which are scoped in a +normal-scoped CDI context have to be serializable. So by default it +is not allowed by CDI to provide a producer-method which exposes, for example, a +conversation scoped <code>EntityManager</code> as it is. We <strong>do not</strong> recommend this approach and therefore it is not available out-of-the-box. +However, if you really need this approach to avoid calling <code>#merge</code> for +your detached entities, it is pretty simple to add this functionality.</p> +</div> +<div class="listingblock"> +<div class="title">Usage of a Simple extended EntityManager</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Inject</span> +<span class="directive">private</span> EntityManager entityManager;</code></pre> +</div> +</div> +<div class="paragraph"> +<p>As you see the usage is the same. You <strong>do not</strong> have to use +<code>ExtendedEntityManager</code> at the injection point. It is just needed in the +producer-method:</p> +</div> +<div class="listingblock"> +<div class="title">Producer for an extended EntityManager (non-EE server)</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="comment">//...</span> +<span class="directive">public</span> <span class="type">class</span> <span class="class">ExtendedEntityManagerProducer</span> +{ + <span class="comment">//or manual bootstrapping</span> + <span class="annotation">@PersistenceContext</span> + <span class="directive">private</span> EntityManager entityManager; + + <span class="annotation">@Produces</span> + <span class="annotation">@RequestScoped</span> + <span class="directive">protected</span> ExtendedEntityManager createEntityManager() + { + <span class="keyword">return</span> <span class="keyword">new</span> ExtendedEntityManager(<span class="local-variable">this</span>.entityManager); + } + + <span class="directive">protected</span> <span class="type">void</span> closeEntityManager(<span class="annotation">@Disposes</span> ExtendedEntityManager entityManager) + { + <span class="keyword">if</span> (entityManager.isOpen()) + { + entityManager.close(); + } + } +}</code></pre> +</div> +</div> +<div class="listingblock"> +<div class="title">Producer for an extended EntityManager (EE server)</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@ApplicationScoped</span> +<span class="directive">public</span> <span class="type">class</span> <span class="class">ExtendedEntityManagerProducer</span> +{ + <span class="annotation">@PersistenceUnit</span> + <span class="directive">private</span> EntityManagerFactory entityManagerFactory; + + <span class="annotation">@Produces</span> + <span class="annotation">@Default</span> + <span class="annotation">@RequestScoped</span> + <span class="directive">public</span> ExtendedEntityManager create() + { + <span class="keyword">return</span> <span class="keyword">new</span> ExtendedEntityManager(<span class="local-variable">this</span>.entityManagerFactory.createEntityManager()); + } + + <span class="directive">public</span> <span class="type">void</span> dispose(<span class="annotation">@Disposes</span> <span class="annotation">@Default</span> ExtendedEntityManager entityManager) + { + <span class="keyword">if</span> (entityManager.isOpen()) + { + entityManager.close(); + } + } +}</code></pre> +</div> +</div> +<div class="listingblock"> +<div class="title">Implementation of a simple extended EntityManager</div> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Typed</span>() +<span class="directive">public</span> <span class="type">class</span> <span class="class">ExtendedEntityManager</span> <span class="directive">implements</span> EntityManager, <span class="predefined-type">Serializable</span> +{ + <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">long</span> serialVersionUID = <span class="integer">3770954229283539616L</span>; + + <span class="directive">private</span> <span class="directive">transient</span> EntityManager wrapped; + + <span class="directive">protected</span> ExtendedEntityManager() + { + } + + <span class="directive">public</span> ExtendedEntityManager(EntityManager wrapped) + { + <span class="local-variable">this</span>.wrapped = wrapped; + } + + <span class="comment">/* + * generated + */</span> + <span class="comment">//delegate all calls to this.wrapped - most IDEs allow to generate it</span> +}</code></pre> +</div> +</div> +<div class="paragraph"> +<p>This approach just works if it <strong>does not come to serialization</strong> of this +wrapper, for example 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 do not recommend</strong> +such an approach.</p> +</div> +</div> +</div> +<div class="sect1"> +<h2 id="_jta_support">JTA Support</h2> +<div class="sectionbody"> +<div class="paragraph"> +<p>By default the transaction-type used by <code>@Transactional</code> is +<code>RESOURCE_LOCAL</code>. If you configure <code>transaction-type="JTA"</code> in the +persistence.xml file, 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> +<div class="listingblock"> +<div class="content"> +<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag"><beans></span> + <span class="tag"><alternatives></span> + <span class="tag"><class></span>org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy<span class="tag"></class></span> + <span class="tag"></alternatives></span> +<span class="tag"></beans></span></code></pre> +</div> +</div> +<div class="paragraph"> +<p>Alternatively, you may expect that your transactions are started at a higher level, e.g. you’re exposing a REST API +and the endpoints themselves are either <code>@Transactional</code> or Stateless session beans, either with container managed +Transactions, you would use <code>org.apache.deltaspike.jpa.impl.transaction.ContainerManagedTransactionStrategy</code>. This +is the strategy to use if you are leveraging <code>@PersistenceContext</code> to inject your <code>EntityManager</code>.</p> +</div> +<div class="paragraph"> +<p>If you have multiple persistence units and you have to use both +transaction types or the settings for development have to be different +than the production settings, you can use +<code>org.apache.deltaspike.jpa.impl.transaction.EnvironmentAwareTransactionStrategy</code> +instead.</p> +</div> +<div class="admonitionblock note"> +<table> +<tr> +<td class="icon"> +<i class="fa icon-note" title="Note"></i> +</td> +<td class="content"> +In case of some versions of Weld - including several versions of JBoss EAP/Wildfly and Websphere Liberty Profile - +or OpenWebBeans in BDA mode - which is not the default one, you have +to configure it as a <a href="spi.html#GlobalAlternative">global alternative</a> instead of an <code>alternative</code> in +<code>beans.xml</code>. That means you have to add, for example, +<code>globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy +=org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy</code> or +<code>globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy = org.apache.deltaspike.jpa.impl.transaction.ContainerManagedTransactionStrategy</code> +to <code>/META-INF/apache-deltaspike.properties</code>. +</td> +</tr> +</table> +</div> +</div> +</div> + </div> + </div> + +
[... 69 lines stripped ...]