blob: bf5b423ab15bbb988774e079694dd8478dc09c84 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title>Implementing the Solution | EclipseLink 2.7 Understanding EclipseLink</title>
<meta name="generator" content="Oracle DARB XHTML Converter (Mode = document) - Version 1.0.22 Build 1" />
<meta name="date" content="2014-06-10T10:35:15Z" />
<meta name="robots" content="noarchive" />
<meta name="doctitle" content="Implementing the Solution" />
<meta name="relnum" content="Release 2.7" />
<link rel="stylesheet" type="text/css" href="../../dcommon/style.css" media="screen" />
<link rel="copyright" href="../../dcommon/html/cpyr.htm" title="Copyright" type="text/html" />
<link rel="start" href="../../index.htm" title="Home" type="text/html" />
<link rel="contents" href="toc.htm" title="Contents" type="text/html" />
<link rel="prev" href="qcn001.htm" title="Previous" type="text/html" />
<link rel="next" href="qcn003.htm" title="Next" type="text/html" />
<!-- START: Disqus --><script type="text/javascript"> var disqus_developer = 0; </script><!-- END: Disqus --><!-- START: Sharethis --><script type="text/javascript">var switchTo5x=true;</script><script type="text/javascript" src="http://w.sharethis.com/button/buttons.js"></script><script type="text/javascript" src="http://s.sharethis.com/loader.js"></script> <!-- END: Sharethis --></head>
<body bgcolor="#FFFFFF"><iframe id="docheader" frameborder="0" framemargin="0" scrolling="no" src="../../dcommon/header.html"></iframe><script src="http://www.google.com/jsapi" type="text/javascript"></script><script type="text/javascript"> google.load('search', '1', {language : 'en'}); google.setOnLoadCallback(function() { var customSearchOptions = {}; var googleAnalyticsOptions = {}; googleAnalyticsOptions['queryParameter'] = 'q'; googleAnalyticsOptions['categoryParameter'] = ''; customSearchOptions['googleAnalyticsOptions'] = googleAnalyticsOptions; var customSearchControl = new google.search.CustomSearchControl( '016171230611334810008:enkkfjmsqju', customSearchOptions); customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET); var options = new google.search.DrawOptions(); options.setSearchFormRoot('cse-search-form'); customSearchControl.draw('cse', options); }, true);</script><link rel="stylesheet" href="http://www.google.com/cse/style/look/default.css" type="text/css" /><div id="cse" style="width:100%;"></div>
<div class="header"><a id="top" name="top"></a>
<table class="simple oac_no_warn" summary="" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td align="left" valign="top"><font face="helvetica, arial, sans-serif"><b>EclipseLink Solutions Guide for EclipseLink</b><br />
Release 2.7</div></td>
<td valign="bottom" align="right" width="144">
<table class="simple oac_no_warn" summary="" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td>&nbsp;</td>
<td align="center" valign="top"><a href="toc.htm"><img src="../../dcommon/images/contents.png" alt="Go To Table Of Contents" border="0" height="16" width="16" /><br />
</td><td>&nbsp;</td><td align="center"><a href="../../" target="_top" class="external text" title="Search" rel="nofollow"><img src="../../dcommon/images/search.png" alt="Search" style="border:0;" /><br /><span class="mini"></span></a></td><td>&nbsp;</td><td align="center"><a href="../eclipselink_otlcg.pdf" title="PDF" target="_blank"><img src="../../dcommon/images/pdf_icon.png" style="padding-right:5px;border:0" alt="PDF"></a></td>
</tr>
</table>
</td>
</tr>
</table>
<hr />
<table class="navigation simple oac_no_warn" summary="" cellspacing="0" cellpadding="0" width="100" align="center">
<tr>
<td align="center"><a href="qcn001.htm"><img src="../../dcommon/images/larrow.png" alt="Previous" border="0" height="16" width="16" /></a></td>
<td align="center"><a href="qcn003.htm"><img src="../../dcommon/images/rarrow.png" alt="Next" border="0" height="16" width="16" /></a></td>
<td>&nbsp;</td>
</tr>
</table>
</div>
<!-- class="header" -->
<div class="ind"><!-- End Header --><a id="A1099145" name="A1099145"></a><a id="TLADG1005" name="TLADG1005"></a>
<div class="sect1"><!-- infolevel="all" infotype="General" -->
<h1 class="sect1"><font face="arial, helvetica, sans-serif" color="#330099">Implementing the Solution</font></h1>
<p>This section contains the following tasks to enable shared caching in a JPA environment:</p>
<ul>
<li>
<p><a href="#CHDBAJED">Task 1: Set up the Database and Tables</a></p>
</li>
<li>
<p><a href="#CHDDJAIE">Task 2: Grant User Permissions</a></p>
</li>
<li>
<p><a href="#CHDFIGGJ">Task 3: Set the Classpath</a></p>
</li>
<li>
<p><a href="#CHDJCFDD">Task 4: Identify Classes that will Participate in Change Notification</a></p>
</li>
<li>
<p><a href="#CHDBCIIE">Task 5: Add the Database Event Listener</a></p>
</li>
<li>
<p><a href="#CHDIIICG">Task 6: Edit the Java Files</a></p>
</li>
</ul>
<a id="CHDBAJED" name="CHDBAJED"></a><a id="TLADG1006" name="TLADG1006"></a>
<div class="sect2"><!-- infolevel="all" infotype="General" -->
<h2 class="sect2"><font face="arial, helvetica, sans-serif" color="#330099">Task 1: Set up the Database and Tables</font></h2>
<p>The solution presumes that you are working with an Oracle 11gR2 (11.2) or higher database that contains the tables that you are interested in.</p>
</div>
<!-- class="sect2" -->
<a id="CHDDJAIE" name="CHDDJAIE"></a><a id="TLADG1007" name="TLADG1007"></a>
<div class="sect2"><!-- infolevel="all" infotype="General" -->
<h2 class="sect2"><font face="arial, helvetica, sans-serif" color="#330099">Task 2: Grant User Permissions</font></h2>
<p>Among other permissions, the database user must be granted the <code>CHANGE</code> <code>NOTIFICATION</code> privilege. To do this, you must have a DBA privilege, such as <code>SYS</code>, or have your database administrator apply it:</p>
<p><code>grant change notification to</code> <em><code>user</code></em></p>
<p>The following example illustrates granting the change notification privilege to user <code>SCOTT</code>.</p>
<pre xml:space="preserve" class="oac_no_warn">
...
define user="SCOTT"
define pass="tiger"
grant create session, alter session to &amp;&amp;user
/
grant resource, connect to &amp;&amp;user
/
grant select any dictionary to &amp;&amp;user
/
grant select any table to &amp;&amp;user
/
<strong><code>grant change notification to &amp;&amp;user</code></strong>
/
...
</pre></div>
<!-- class="sect2" -->
<a id="CHDFIGGJ" name="CHDFIGGJ"></a><a id="TLADG1008" name="TLADG1008"></a>
<div class="sect2"><!-- infolevel="all" infotype="General" -->
<h2 class="sect2"><font face="arial, helvetica, sans-serif" color="#330099">Task 3: Set the Classpath</font></h2>
<p>Ensure that the <code>eclipselink.jar</code> EclipseLink library, the <code>ojdbc6.jar</code> JDBC library, the <code>persistence.jar</code> JPA library, and the domain classes are present on the classpath.</p>
</div>
<!-- class="sect2" -->
<a id="CHDJCFDD" name="CHDJCFDD"></a><a id="TLADG1009" name="TLADG1009"></a>
<div class="sect2">
<h2 class="sect2"><font face="arial, helvetica, sans-serif" color="#330099">Task 4: Identify Classes that will Participate in Change Notification</font></h2>
<p>By default, all entities in the domain will participate in change notification. There are several different ways to limit the entities that will participate. For example, the entity classes can be indicated by the <code>&lt;entity class ...&gt;</code> element in the <code>orm.xml</code> file, indicated with the <code>&lt;exclude-unlisted-classes&gt;</code> element in the <code>persistence.xml</code> file, or contained in a JAR file.</p>
<div align="center">
<div class="inftblnote"><br />
<table class="Note oac_no_warn" summary="" border="1" width="80%" frame="hsides" rules="groups" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<td align="left">
<p class="note"><img src="../../dcommon/images/note_icon.png" width="16" height="16" alt="Note" style="vertical-align:middle;padding-right:5px;" />Note:</p>
<p>The <code>&lt;exclude-unlisted-classes&gt;</code> element is not intended for use in the Java SE environment.</p>
</td>
</tr>
</tbody>
</table>
<br /></div>
<!-- class="inftblnote" --></div>
<p>Entity classes can also be excluded by using a <code>Cache</code> annotation attribute in the Java files. For more information, see <a href="#CHDGBGAG">Exclude Classes from Change Notification (Optional).</a></p>
<p>Another way to identify the entity classes is to use the <code>&lt;class&gt;</code> element in the <code>persistence.xml</code> file. The following example indicates that the <code>Order</code>, <code>OrderLine</code>, and <code>Customer</code> classes in the <code>model</code> package will participate in change notification. For an example of a complete <code>persistence.xml</code> file, see <a href="#CHDECAAF">Example 20-1</a>.</p>
<pre xml:space="preserve" class="oac_no_warn">
...
&lt;class&gt;model.Order&lt;/class&gt;
&lt;class&gt;model.OrderLine&lt;/class&gt;
&lt;class&gt;model.Customer&lt;/class&gt;
...
</pre></div>
<!-- class="sect2" -->
<a id="CHDBCIIE" name="CHDBCIIE"></a><a id="TLADG1010" name="TLADG1010"></a>
<div class="sect2">
<h2 class="sect2"><font face="arial, helvetica, sans-serif" color="#330099">Task 5: Add the Database Event Listener</font></h2>
<p>Use the <code>eclipselink.cache.database-event-listener</code> property to identify the database event listener. The <code>org.eclipse.persistence.platform.database.oracle.dcn.OracleChangeNotificationListener</code> class is the listener for EclipseLink Database Change Notification. This allows the EclipseLink cache to be invalidated by database events.</p>
<p>The following example illustrates the <code>eclipselink.cache.database-event-listener</code> property configured with the <code>OracleChangeNotificationListener</code> class. For an example of a complete <code>persistence.xml</code> file, see <a href="#CHDECAAF">Example 20-1</a>.</p>
<pre xml:space="preserve" class="oac_no_warn">
...
&lt;properties&gt;
&lt;property name="eclipselink.cache.database-event-listener" value="org.eclipse.persistence.platform.database.oracle.dcn.OracleChangeNotificationListener"/&gt;
&lt;/properties&gt;
...
</pre>
<p>Note that you can also use:</p>
<pre xml:space="preserve" class="oac_no_warn">
&lt;property name="eclipselink.cache.database-event-listener" value="DCN"&gt;
</pre>
<p><a href="#CHDECAAF">Example 20-1</a> illustrates an example of a complete <code>persistence.xml</code> file. The classes that will participate in change notification are the <code>Order</code>, <code>OrderLine</code>, and <code>Customer</code> classes from the <code>model</code> package. The <code>eclipselink.cache.database-event-listener</code> property is set to the full path of the <code>OracleChangeNotificationListener</code> class.</p>
<div align="center">
<div class="inftblnote"><br />
<table class="Note oac_no_warn" summary="" border="1" width="80%" frame="hsides" rules="groups" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<td align="left">
<p class="note"><img src="../../dcommon/images/note_icon.png" width="16" height="16" alt="Note" style="vertical-align:middle;padding-right:5px;" />Note:</p>
<p>A <code>&lt;provider&gt;</code> tag is optional if running in a container where EclipseLink is the default provider.</p>
</td>
</tr>
</tbody>
</table>
<br /></div>
<!-- class="inftblnote" --></div>
<div class="example"><a id="CHDECAAF" name="CHDECAAF"></a><a id="TLADG1011" name="TLADG1011"></a>
<p><strong><em><font face="arial, helvetica, sans-serif">Example 20-1 Sample persistence.xml File</font></em></strong></p>
<pre xml:space="preserve" class="oac_no_warn">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_2_0.xsd"
version="2.0"&gt;
&lt;persistence-unit name="acme" transaction-type="RESOURCE_LOCAL"&gt;
&lt;provider&gt;org.eclipse.persistence.jpa.PersistenceProvider&lt;/provider&gt;
<strong> &lt;class&gt;model.Order&lt;/class&gt;</strong>
<strong>&lt;class&gt;model.OrderLine&lt;/class&gt;</strong>
<strong>&lt;class&gt;model.Customer&lt;/class&gt;</strong>
&lt;exclude-unlisted-classes&gt;false&lt;/exclude-unlisted-classes&gt;
&lt;properties&gt;
<strong>&lt;property name="eclipselink.cache.database-event-listener" value="DCN"/&gt;</strong>
&lt;/properties&gt;
&lt;/persistence-unit&gt;
&lt;/persistence&gt;
</pre></div>
<!-- class="example" --></div>
<!-- class="sect2" -->
<a id="CHDIIICG" name="CHDIIICG"></a><a id="TLADG1012" name="TLADG1012"></a>
<div class="sect2"><!-- infolevel="all" infotype="General" -->
<h2 class="sect2"><font face="arial, helvetica, sans-serif" color="#330099">Task 6: Edit the Java Files</font></h2>
<p>Typically, to participate in change notification, no changes are needed to the Java classes which correspond to database tables. However, setting optimistic locking with the <code>@Version</code> annotation is strongly suggested.</p>
<p>If you want to exclude classes that are listed in the persistence unit, you can tag them in the Java files. EclipseLink tracks changes only to the primary table. If you want changes to secondary tables to also be tracked, you can indicate this in the Java files.</p>
<a id="TLADG1013" name="TLADG1013"></a>
<div class="sect3"><!-- infolevel="all" infotype="General" --><a id="sthref227" name="sthref227"></a>
<h3 class="sect3"><font face="arial, helvetica, sans-serif" color="#330099">Set Optimistic Locking</font></h3>
<p>Oracle strongly suggests that you use optimistic locking: writes on stale data will fail and automatically invalidate the cache. Include an <code>@Version</code> annotation in your entity; the version column in the primary table will always be updated, and the older version of the object will always be invalidated.</p>
<p>In <a href="#CHDJGCBF">Example 20-2</a> the <code>@Version</code> annotation is defined for the entity <code>Customer</code>. Note that getters and setters are defined for the <code>version</code> variable.</p>
<div class="example"><a id="CHDJGCBF" name="CHDJGCBF"></a><a id="TLADG1014" name="TLADG1014"></a>
<p><strong><em><font face="arial, helvetica, sans-serif">Example 20-2 Defining the @Version Annotation</font></em></strong></p>
<pre xml:space="preserve" class="oac_no_warn">
...
@Entity
@Table(name="DBE_CUSTOMER")
public class Customer implements Serializable {
@Id
@GeneratedValue(generator="CUST_SEQ")
@TableGenerator(name="CUST_SEQ")
@Column(name="CUST_NUMBER")
private long id;
<strong><code> @Version</code></strong>
<strong><code> private long version;</code></strong>
...
<strong><code> public long getVersion() </code></strong>{
<strong><code> return version;</code></strong>
}
<strong><code> public void setVersion(long version) {</code></strong>
<strong><code> this.version = version;</code></strong>
}
...
</pre></div>
<!-- class="example" --></div>
<!-- class="sect3" -->
<a id="CHDGBGAG" name="CHDGBGAG"></a><a id="TLADG1015" name="TLADG1015"></a>
<div class="sect3">
<h3 class="sect3"><font face="arial, helvetica, sans-serif" color="#330099">Exclude Classes from Change Notification (Optional)</font></h3>
<p>Use the <code>databaseChangeNotificationType</code> attribute of the <code>Cache</code> annotation to identify the classes for which you do not want change notifications. To exclude a class from change notification, set the attribute to <code>DatabaseChangeNotificationType.NONE</code>, as illustrated in the following example.</p>
<pre xml:space="preserve" class="oac_no_warn">
...
@Entity
<strong><code>@Cache(databaseChangeNotificationType=DatabaseChangeNotificationType.NONE)</code></strong>
public class Order {
...
</pre></div>
<!-- class="sect3" -->
<a id="TLADG1016" name="TLADG1016"></a>
<div class="sect3"><a id="sthref228" name="sthref228"></a>
<h3 class="sect3"><font face="arial, helvetica, sans-serif" color="#330099">Track Changes in Secondary Tables (Optional)</font></h3>
<p>EclipseLink tracks changes only to the primary table. If any updates occur in a secondary table, EclipseLink will not invalidate the object. If you want changes to secondary tables to be tracked as well, add the <code>@Version</code> annotation to the entity.</p>
<p>Oracle DCN listens only for events from the primary table. It does not track changes in secondary tables, or relationships tables. The reason for this is that Oracle DCN only tracks the <code>ROWID</code>, so there is no correlation from the <code>ROWID</code> of the primary, secondary and relationship tables. Thus, to receive events when a secondary or relationship table changes, the version in the primary table must change so that the event is returned.</p>
</div>
<!-- class="sect3" --></div>
<!-- class="sect2" --></div>
<!-- class="sect1" --></div>
<!-- class="ind" -->
<!-- Start Footer -->
<div class="footer">
<hr />
<table class="simple oac_no_warn" summary="" cellspacing="0" cellpadding="0" width="100%">
<col width="33%" />
<col width="*" />
<col width="33%" />
<tr>
<td valign="bottom">
<table class="navigation simple oac_no_warn" summary="" cellspacing="0" cellpadding="0" width="100" align="center">
<col width="*" />
<col width="48%" />
<col width="48%" />
<tr>
<td>&nbsp;</td>
<td align="center"><a href="qcn001.htm"><img src="../../dcommon/images/larrow.png" alt="Previous" border="0" height="16" width="16" /></a></td>
<td align="center"><a href="qcn003.htm"><img src="../../dcommon/images/rarrow.png" alt="Next" border="0" height="16" width="16" /></a></td>
</tr>
</table>
</td>
<td align="center" width="34%"><a href="http://www.eclipse.org/eclipselink/" title="EclipseLink home"><img src="../../dcommon/images/ellogo.png" alt="EclipseLink" width="150" border="0" /></a><br />
<font size="-2">Copyright&nbsp;&copy;&nbsp;2014,&nbsp;Oracle&nbsp;and/or&nbsp;its&nbsp;affiliates.&nbsp;All&nbsp;rights&nbsp;reserved.</font> <a href="../../dcommon/html/cpyr.htm"><br />
<td valign="bottom" align="right">
<table class="simple oac_no_warn" summary="" cellspacing="0" cellpadding="0" width="225">
<tr>
<td>&nbsp;</td>
<td align="center" valign="top"><a href="toc.htm"><img src="../../dcommon/images/contents.png" alt="Go To Table Of Contents" border="0" height="16" width="16" /><br />
</td><td>&nbsp;</td><td align="center"><a href="../../" target="_top" class="external text" title="Search" rel="nofollow"><img src="../../dcommon/images/search.png" alt="Search" style="border:0;" /><br /><span class="mini"></span></a></td><td>&nbsp;</td><td align="center"><a href="../eclipselink_otlcg.pdf" title="PDF" target="_blank"><img src="../../dcommon/images/pdf_icon.png" style="padding-right:5px;border:0" alt="PDF"></a></td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<!-- class="footer" -->
<div id="copyright">Copyright &copy; 2014 by The Eclipse Foundation under the <a href="http://www.eclipse.org/org/documents/epl-v10.php">Eclipse Public License (EPL)</a><br /> <script type="text/javascript">var LastUpdated = document.lastModified;document.writeln ("Updated: " + LastUpdated);</script> </div><!-- START: Analytics --><script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-1608008-2']); _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><!-- END: Analytics --><!-- START: Sharethis --><script>var options={ "publisher": "e2fe9e07-fab6-4f84-83ea-0991b429842c", "position": "right", "ad": { "visible": false, "openDelay": 5, "closeDelay": 0}};var st_hover_widget = new sharethis.widgets.hoverbuttons(options);</script><!-- END: Sharethis --></body>
</html>