blob: aca76f4aedc7834c5eb0c476d28867bf22120c2e [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Apache TomEE</title>
<meta name="description"
content="Apache TomEE is a lightweight, yet powerful, JavaEE Application server with feature rich tooling." />
<meta name="keywords" content="tomee,asf,apache,javaee,jee,shade,embedded,test,junit,applicationcomposer,maven,arquillian" />
<meta name="author" content="Luka Cvetinovic for Codrops" />
<link rel="icon" href="../../favicon.ico">
<link rel="icon" type="image/png" href="../../favicon.png">
<meta name="msapplication-TileColor" content="#80287a">
<meta name="theme-color" content="#80287a">
<link rel="stylesheet" type="text/css" href="../../css/normalize.css">
<link rel="stylesheet" type="text/css" href="../../css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="../../css/owl.css">
<link rel="stylesheet" type="text/css" href="../../css/animate.css">
<link rel="stylesheet" type="text/css" href="../../fonts/font-awesome-4.1.0/css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="../../fonts/eleganticons/et-icons.css">
<link rel="stylesheet" type="text/css" href="../../css/jqtree.css">
<link rel="stylesheet" type="text/css" href="../../css/idea.css">
<link rel="stylesheet" type="text/css" href="../../css/cardio.css">
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-2717626-1']);
_gaq.push(['_setDomainName', 'apache.org']);
_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="preloader">
<img src="../../img/loader.gif" alt="Preloader image">
</div>
<nav class="navbar">
<div class="container">
<div class="row"> <div class="col-md-12">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
<span>
<img src="../../img/logo-active.png">
</span>
Apache TomEE
</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right main-nav">
<li><a href="../../docs.html">Documentation</a></li>
<li><a href="../../community/index.html">Community</a></li>
<li><a href="../../security/security.html">Security</a></li>
<li><a href="../../download-ng.html">Downloads</a></li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div></div>
</div>
<!-- /.container-fluid -->
</nav>
<div id="main-block" class="container main-block">
<div class="row title">
<div class="col-md-12">
<div class='page-header'>
<h1>JPA Concepts</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h1 id="_jpa_101" class="sect0">JPA 101</h1>
<div class="paragraph">
<p>If there&#8217;s one thing you have to understand to successfully use JPA
(Java Persistence API) it&#8217;s the concept of a <em>Cache</em>. Almost everything
boils down to the Cache at one point or another. Unfortunately the Cache
is an internal thing and not exposed via the JPA API classes, so it not
easy to touch or feel from a coding perspective.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s a quick cheat sheet of the JPA world:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>A <strong>Cache</strong> is a <strong>copy of data</strong>, copy meaning pulled from but living
outside the database.</p>
</li>
<li>
<p><strong>Flushing</strong> a Cache is the act of putting modified data back into the
database.</p>
</li>
<li>
<p>A <strong>PersistenceContext</strong> is essentially a Cache. It also tends to have
it&#8217;s own non-shared database connection.</p>
</li>
<li>
<p>An <strong>EntityManager</strong> represents a PersistenceContext (and therefore a
Cache)</p>
</li>
<li>
<p>An <strong>EntityManagerFactory</strong> creates an EntityManager (and therefore a
PersistenceContext/Cache)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Comparing <code>RESOURCE_LOCAL</code> and <code>JTA</code> persistence contexts</p>
</div>
<div class="paragraph">
<p>With &lt;persistence-unit transaction-type="<strong>RESOURCE_LOCAL</strong>"&gt; <strong>you</strong> are
responsible for EntityManager (PersistenceContext/Cache) creating and
tracking&#8230;&#8203;</p>
</div>
<div class="ulist">
<ul>
<li>
<p>You <strong>must</strong> use the <strong>EntityManagerFactory</strong> to get an EntityManager</p>
</li>
<li>
<p>The resulting <strong>EntityManager</strong> instance <strong>is</strong> a PersistenceContext/Cache</p>
</li>
<li>
<p>An <strong>EntityManagerFactory</strong> can be injected via the <strong>@PersistenceUnit</strong>
annotation only (not <code>@PersistenceContext</code>)</p>
</li>
<li>
<p>You are <strong>not</strong> allowed to use @PersistenceContext to refer to a unit of
type RESOURCE_LOCAL</p>
</li>
<li>
<p>You <strong>must</strong> use the <strong>EntityTransaction</strong> API to begin/commit around
<strong>every</strong> call to your EntityManger</p>
</li>
<li>
<p>Calling entityManagerFactory.createEntityManager() twice results in
<strong>two</strong> separate EntityManager instances and therefor <strong>two</strong> separate
PersistenceContexts/Caches.</p>
</li>
<li>
<p>It is <strong>almost never</strong> a good idea to have more than one <strong>instance</strong> of
an EntityManager in use (don&#8217;t create a second one unless you&#8217;ve
destroyed the first)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>With &lt;persistence-unit transaction-type="<strong>JTA</strong>"&gt; the <strong>container</strong> will do
EntityManager (PersistenceContext/Cache) creating and tracking&#8230;&#8203;</p>
</div>
<div class="ulist">
<ul>
<li>
<p>You <strong>cannot</strong> use the <strong>EntityManagerFactory</strong> to get an EntityManager</p>
</li>
<li>
<p>You can only get an <strong>EntityManager</strong> supplied by the <strong>container</strong></p>
</li>
<li>
<p>An <strong>EntityManager</strong> can be injected via the <strong>@PersistenceContext</strong>
annotation only (not <code>@PersistenceUnit</code>)</p>
</li>
<li>
<p>You are <strong>not</strong> allowed to use @PersistenceUnit to refer to a unit of
type JTA</p>
</li>
<li>
<p>The <strong>EntityManager</strong> given by the container is a <strong>reference</strong> to the
PersistenceContext/Cache associated with a JTA Transaction.</p>
</li>
<li>
<p>If no JTA transaction is in progress, the EntityManager <strong>cannot be
used</strong> because there is no PersistenceContext/Cache.</p>
</li>
<li>
<p>Everyone with an EntityManager reference to the <strong>same unit</strong> in the
<strong>same transaction</strong> will automatically have a reference to the <strong>same
PersistenceContext/Cache</strong></p>
</li>
<li>
<p>The PersistenceContext/Cache is <strong>flushed</strong> and cleared at JTA <strong>commit</strong>
time</p>
</li>
</ul>
</div>
<h1 id="_cache_persistencecontext" class="sect0">Cache == PersistenceContext</h1>
<div class="paragraph">
<p>The concept of a database cache is an extremely important concept to be
aware of. Without a copy of the data in memory (i.e. a cache) when you
call account.getBalance() the persistence provider would have to go read
the value from the database. Calling account.getBalance() several times
would cause several trips to the database. This would obviously be a big
waste of resources. The other side of having a cache is that when you
call account.setBalance(5000) it also doesn&#8217;t hit the database
(usually). When the cache is "flushed" the data in it is sent to the
database via as many SQL updates, inserts and deletes as are required.
That is the basics of java persistence of any kind all wrapped in a
nutshell. If you can understand that, you&#8217;re good to go in nearly any
persistence technology java has to offer.</p>
</div>
<div class="paragraph">
<p>Complications can arise when there is more than one
PersistenceContext/Cache relating the same data in the same transaction.
In any given transaction you want exactly one PersistenceContext/Cache
for a given set of data. Using a JTA unit with an EntityManager created
by the container will always guarantee that this is the case. With a
RESOURCE_LOCAL unit and an EntityManagerFactory you should create and
use exactly one EntityManager instance in your transaction to ensure
there is only one active PersistenceContext/Cache for the given set of
data active against the current transaction.</p>
</div>
<h1 id="_caches_and_detaching" class="sect0">Caches and Detaching</h1>
<div class="paragraph">
<p>Detaching is the concept of a persistent object <strong>leaving</strong> the
PersistenceContext/Cache. Leaving means that any updates made to the
object are <strong>not</strong> reflected in the PersistenceContext/Cache. An object
will become Detached if it somehow <strong>lives longer</strong> or is <strong>used outside</strong>
the scope of the PersistenceContext/Cache.</p>
</div>
<div class="paragraph">
<p>For a JTA unit, the PersistenceContext/Cache will live as long as the
transaction does. When a transaction completes (commits or rollsback)
all objects that were in the PersistenceContext/Cache are Detached. You
can still use them, but they are no longer associated with a
PersistenceContext/Cache and modifications on them will <strong>not</strong> be
reflected in a PersistenceContext/Cache and therefore not the database
either.</p>
</div>
<div class="paragraph">
<p>Serializing objects that are currently in a PersistenceContext/Cache
will also cause them to Detach.</p>
</div>
<div class="paragraph">
<p>In some cases objects or collections of objects that become Detached may
not have all the data you need. This can be because of lazy loading.
With lazy loading, data isn&#8217;t pulled from the database and into the
PersistenceContext/Cache until it is requested in code. In many cases
the Collections of persistent objects returned from an
javax.persistence.Query.getResultList() call are completely empty until
you iterate over them. A side effect of this is that if the Collection
becomes Detached before it&#8217;s been fully read it will be permanently
empty and of no use and calling methods on the Detached Collection can
cause strange errors and exceptions to be thrown. If you wish to Detach
a Collection of persistent objects it is always a good idea to iterate
over the Collection at least once.</p>
</div>
<div class="paragraph">
<p>You <strong>cannot</strong> call EntityManager.persist() or EntityManager.remove() on a
Detached object.</p>
</div>
<div class="paragraph">
<p>Calling EntityManager.merge() will re-attach a Detached object.</p>
</div>
<h1 id="_valid_resource_local_unit_usage" class="sect0">Valid RESOURCE_LOCAL Unit usage</h1>
<div class="paragraph">
<p>Servlets and EJBs can use RESOURCE_LOCAL persistence units through the
EntityManagerFactory as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"&gt;
&lt;!-- Tutorial "unit" --&gt;
&lt;persistence-unit name="Tutorial" transaction-type="RESOURCE_LOCAL"&gt;
&lt;non-jta-data-source&gt;myNonJtaDataSource&lt;/non-jta-data-source&gt;
&lt;class&gt;org.superbiz.jpa.Account&lt;/class&gt;
&lt;/persistence-unit&gt;
&lt;/persistence&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>And referenced as follows</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceUnit;
public class MyEjbOrServlet ... {
@PersistenceUnit(unitName="Tutorial")
private EntityManagerFactory factory;
// Proper exception handling left out for simplicity
public void ejbMethodOrServletServiceMethod() throws Exception {
EntityManager entityManager = factory.createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
Account account = entityManager.find(Account.class, 12345);
account.setBalance(5000);
entityTransaction.commit();
}
...
}</code></pre>
</div>
</div>
<div class="sect1">
<h2 id="_valid_jta_unit_usage">Valid JTA Unit usage</h2>
<div class="sectionbody">
<div class="paragraph">
<p>EJBs can use JTA persistence units through the EntityManager as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"&gt;
&lt;!-- Tutorial "unit" --&gt;
&lt;persistence-unit name="Tutorial" transaction-type="JTA"&gt;
&lt;jta-data-source&gt;myJtaDataSource&lt;/jta-data-source&gt;
&lt;non-jta-data-source&gt;myNonJtaDataSource&lt;/non-jta-data-source&gt;
&lt;class&gt;org.superbiz.jpa.Account&lt;/class&gt;
&lt;/persistence-unit&gt;
&lt;/persistence&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>And referenced as follows</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless
public class MyEjb implements MyEjbInterface {
@PersistenceContext(unitName = "Tutorial")
private EntityManager entityManager;
// Proper exception handling left out for simplicity
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void ejbMethod() throws Exception {
Account account = entityManager.find(Account.class, 12345);
account.setBalance(5000);
}
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-sm-6 text-center-mobile">
<h3 class="white">Be simple. Be certified. Be Tomcat.</h3>
<h5 class="light regular light-white">"A good application in a good server"</h5>
<ul class="social-footer">
<li><a href="https://www.facebook.com/ApacheTomEE/"><i class="fa fa-facebook"></i></a></li>
<li><a href="https://twitter.com/apachetomee"><i class="fa fa-twitter"></i></a></li>
<li><a href="https://plus.google.com/communities/105208241852045684449"><i class="fa fa-google-plus"></i></a></li>
</ul>
</div>
<div class="col-sm-6 text-center-mobile">
<div class="row opening-hours">
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../latest/docs/" class="white">Documentation</a></h5>
<ul class="list-unstyled">
<li><a href="../../latest/docs/admin/configuration/index.html" class="regular light-white">How to configure</a></li>
<li><a href="../../latest/docs/admin/file-layout.html" class="regular light-white">Dir. Structure</a></li>
<li><a href="../../latest/docs/developer/testing/index.html" class="regular light-white">Testing</a></li>
<li><a href="../../latest/docs/admin/cluster/index.html" class="regular light-white">Clustering</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../latest/examples/" class="white">Examples</a></h5>
<ul class="list-unstyled">
<li><a href="../../latest/examples/simple-cdi-interceptor.html" class="regular light-white">CDI Interceptor</a></li>
<li><a href="../../latest/examples/rest-cdi.html" class="regular light-white">REST with CDI</a></li>
<li><a href="../../latest/examples/ejb-examples.html" class="regular light-white">EJB</a></li>
<li><a href="../../latest/examples/jsf-managedBean-and-ejb.html" class="regular light-white">JSF</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../community/index.html" class="white">Community</a></h5>
<ul class="list-unstyled">
<li><a href="../../community/contributors.html" class="regular light-white">Contributors</a></li>
<li><a href="../../community/social.html" class="regular light-white">Social</a></li>
<li><a href="../../community/sources.html" class="regular light-white">Sources</a></li>
</ul>
</div>
<div class="col-sm-3 text-center-mobile">
<h5><a href="../../security/index.html" class="white">Security</a></h5>
<ul class="list-unstyled">
<li><a href="http://apache.org/security" target="_blank" class="regular light-white">Apache Security</a></li>
<li><a href="http://apache.org/security/projects.html" target="_blank" class="regular light-white">Security Projects</a></li>
<li><a href="http://cve.mitre.org" target="_blank" class="regular light-white">CVE</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="row bottom-footer text-center-mobile">
<div class="col-sm-12 light-white">
<p>Copyright &copy; 1999-2016 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. Apache TomEE, TomEE, Apache, the Apache feather logo, and the Apache TomEE project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.</p>
</div>
</div>
</div>
</footer>
<!-- Holder for mobile navigation -->
<div class="mobile-nav">
<ul>
<li><a hef="../../latest/docs/admin/index.html">Administrators</a>
<li><a hef="../../latest/docs/developer/index.html">Developers</a>
<li><a hef="../../latest/docs/advanced/index.html">Advanced</a>
<li><a hef="../../community/index.html">Community</a>
</ul>
<a href="#" class="close-link"><i class="arrow_up"></i></a>
</div>
<!-- Scripts -->
<script src="../../js/jquery-1.11.1.min.js"></script>
<script src="../../js/owl.carousel.min.js"></script>
<script src="../../js/bootstrap.min.js"></script>
<script src="../../js/wow.min.js"></script>
<script src="../../js/typewriter.js"></script>
<script src="../../js/jquery.onepagenav.js"></script>
<script src="../../js/tree.jquery.js"></script>
<script src="../../js/highlight.pack.js"></script>
<script src="../../js/main.js"></script>
</body>
</html>