openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From build...@apache.org
Subject svn commit: r841236 [5/35] - in /websites/staging/openjpa/trunk/content: ./ artifacts/ css/ images/ images/datacache-plugin/
Date Sun, 09 Dec 2012 13:13:50 GMT
Added: websites/staging/openjpa/trunk/content/bean-validation-primer.html
==============================================================================
--- websites/staging/openjpa/trunk/content/bean-validation-primer.html (added)
+++ websites/staging/openjpa/trunk/content/bean-validation-primer.html Sun Dec  9 13:13:35 2012
@@ -0,0 +1,1115 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<!--
+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.
+-->
+<html lang="en">
+    <head>
+        <META http-equiv="Content-Type" content="text/html;charset=UTF-8" />
+        <link href="http://openjpa.apache.org/styles/site.css" rel="stylesheet" type="text/css"/>
+        <!-- <link href="http://openjpa.apache.org/styles/type-settings.css" rel="stylesheet" type="text/css"/> -->
+        <link href="./css/type-settings.css" rel="stylesheet" type="text/css"/>
+        <LINK rel="schema.DC" href="http://purl.org/DC/elements/1.0/">
+        <META name="Description" content="Apache OpenJPA -- Bean Validation Primer
" />
+        <META name="Keywords" content="Apache OpenJPA, JPA, JPA 1.0, JSR-220, JPA2, JPA 2.0, JSR-317, " />
+        <META name="Owner" content="dev@openjpa.apache.org" />
+        <META name="Robots" content="index, follow" />
+        <META name="Security" content="Public" />
+        <META name="Source" content="wiki template" />
+        <META name="DC.Date" scheme="iso8601" content="2010-08-11" />
+        <META name="DC.Language" scheme="rfc1766" content="en" />
+        <META name="DC.Rights" content="Copyright © 2006,2010 The Apache Software Foundation" />
+        <META http-equiv="PICS-Label" content='(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))'/>
+
+        <title>
+            Apache OpenJPA --
+        </title>
+    </head>
+    <body>
+        <div class="white_box">
+            <div class="header">
+                <div class="header_l">
+                    <div class="header_r">
+                    </div>
+                </div>
+            </div>
+            <div class="content">
+                <div class="content_l">
+                    <div class="content_r">
+                        <div>
+                            <!-- Banner -->
+                            <TABLE valign="top" border="0" cellspacing="0" cellpadding="5" width="100%" background="images/header-bg3.png">
+                                <TR>
+                                    <TD valing="top" align="left">
+                                        <A href="http://openjpa.apache.org/"><IMG src="images/openjpa-logo.png" border="0" alt="OpenJPA Logo"></A>
+                                    </TD>
+                                    <TD width="100%">
+                                        &nbsp;
+                                    </TD>
+                                    <TD valing="top" align="right">
+                                        <A href="http://www.apache.org/"><IMG src="images/asf_logo_wide2.png" border="0" alt="ASF Logo"></A>
+                                    </TD>
+                                </TR>
+                            </TABLE>
+
+                            <!-- Navigation Bar -->
+                            <div class="bottom_red_bar">
+                                <div id="site-breadcrumbs">
+                                    <!-- Breadcrumbs --
+                                    <a href="/">Home</a>&nbsp;&raquo&nbsp;<a href="/bean-validation-primer.html">Bean Validation Primer
</a>
+                                     -- Breadcrumbs -->
+                                </div>
+                            </div>
+
+                            <!-- Content -->
+                            <table border="0">
+                                <tbody>
+                                    <tr>
+                                        <td valign="top">
+                                            <div class="navigation">
+                                                <div class="navigation_top">
+                                                    <div class="navigation_bottom">
+                                                        <!-- NavigationBar -->
+                                                        <h3><a name="SideNav-Overview"></a><a href="overview.html" title="Overview">Overview</a></h3>
+
+                                                        <ul class="alternate" type="square">
+                                                            <li><a href="quick-start.html" title="Quick Start">Quick Start</a></li>
+                                                            <li><a href="documentation.html" title="Documentation">Documentation</a></li>
+                                                            <li><a href="downloads.html" title="Downloads">Downloads</a></li>
+                                                            <li><a href="site-index.html" title="Site Index">Site Index</a></li>
+                                                            <li><a href="license.html" title="License">License</a></li>
+                                                            <li><a href="privacy-policy.html" title="Privacy Policy">Privacy Policy</a></li>
+                                                        </ul>
+
+                                                        <h3><a name="SideNav-Community"></a><a href="community.html" title="Community">Community</a></h3>
+
+                                                        <ul class="alternate" type="square">
+                                                            <li><a href="index.html#Index-eventsandnews" title="Events and News">Events and News</a></li>
+                                                            <li><a href="found-a-bug.html" title="Found a Bug">Found a Bug</a>?</li>
+                                                            <li><a href="get-involved.html" title="Get Involved">Get Involved</a></li>
+                                                            <li><a href="mailing-lists.html" title="Mailing Lists">Mailing Lists</a></li>
+                                                            <li><a href="committers.html" title="Committers">Committers</a></li>
+                                                            <li><a href="integration.html" title="Integration">Integration</a></li>
+                                                            <li><a href="powered-by.html" title="Powered By">Powered By</a></li>
+                                                            <li><a href="thanks.html" title="Thanks">Thanks</a></li>
+                                                        </ul>
+
+
+                                                        <h3><a name="SideNav-Development"></a><a href="development.html" title="Development">Development</a></h3>
+
+                                                        <ul class="alternate" type="square">
+                                                            <li><a href="http://issues.apache.org/jira/browse/OPENJPA" class="external-link" rel="nofollow">Issue Tracker</a></li>
+                                                            <li><a href="source-code.html" title="Source Code">Source Code</a></li>
+                                                            <li><a href="testing.html" title="Testing">Testing</a></li>
+                                                            <li><a href="tools.html" title="Tools">Tools</a></li>
+                                                            <li><a href="samples.html" title="Samples">Samples</a></li>
+                                                            <li><a href="release-management.html" title="Release Management">Release Management</a></li>
+                                                        </ul>
+
+                                                        <h3>Search</h3>
+
+                                                        <div style="padding: 5px 5px 0px 25px;">
+                                                            <form action="http://www.google.com/search" method="get" style="font-size: 10px;">
+                                                                <input name="ie" type="hidden" value="UTF-8">
+                                                                <input name="oe" type="hidden" value="UTF-8">
+                                                                <input maxlength="255" name="q" size="9" type="text" value=""><br><br>
+                                                                <input name="btnG" type="submit" value="Google">
+                                                                <input name="domains" type="hidden" value="openjpa.apache.org">
+                                                                <input name="sitesearch" type="hidden" value="openjpa.apache.org">
+                                                            </form>
+                                                        </div>
+                                                    </div>
+                                                </div>
+                                            </div>
+                                        </td>
+                                        <td valign="top" width="100%" style="overflow:hidden;">
+                                            <div class="wiki-content">
+                                                <p><a name="BeanValidationPrimer-OpenJPABeanValidationPrimer"></a></p>
+<h1 id="openjpa-bean-validation-primer">OpenJPA Bean Validation Primer</h1>
+<p>A new feature defined by the JPA 2.0 specification is the ability to
+seamlessly integrate with a <a href="http://jcp.org/en/jsr/detail?id=303">JSR-303</a>
+ bean validation provider.   With minimal effort, <a href="http://openjpa.apache.org/openjpa-200.html">OpenJPA 2.0</a>
+ can be coupled with a <a href="http://jcp.org/en/jsr/detail?id=303">JSR-303</a>
+ validation provider to provide runtime data validation.  By combining
+these two technologies, you get a standardized persistence solution with
+the added ability to perform standardized java bean validation.</p>
+<p><a name="BeanValidationPrimer-WhatisBeanValidation?"></a></p>
+<h2 id="what-is-bean-validation">What is Bean Validation?</h2>
+<p>Most applications, especially those that gather input from a user, contain
+a significant amount of code to perform data validation.  It is typically
+custom code, fragmented and littered throughout the application.  Worse,
+there may be duplicate validation code at the presentation (Web) , business
+(EJB), and persistence layers.  The task of keeping duplicate code in synch
+can be especially problematic.  A slight modification in the code at one
+layer can lead to an unforseen breakage in another.</p>
+<p>The Bean Validation API was designed to provide a standardized method for
+validating data within Java beans.  As an added feature, it seemlessly
+integrates with several JEE6 technologies including <a href="http://jcp.org/en/jsr/detail?id=317">JPA 2.0</a>
+, <a href="http://jcp.org/en/jsr/summary?id=322">JCA 1.6</a>
+, and <a href="http://jcp.org/en/jsr/detail?id=314">JSF 2.0</a>
+.  Additionally, JEE6 complaint servers are required to support bean
+validation and must include a validation provider.  While a JEE6
+environment provides some simplified packaging and configuration benefits,
+bean validation works equally well in a JSE environment.  For simplicity,
+this primer will use a JSE environment, but the example code could be used
+within a JEE6 environment with very few modifications.</p>
+<p>While the <a href="http://jcp.org/en/jsr/detail?id=303">JSR-303 specification</a>
+ is very feature rich and extensible, there are three core concepts that
+will be of most interest to the majority of users:  constraints, constraint
+violation handling, and the validator itself.  If you are running in an
+integrated environment like JPA, you will rarely have to concern yourself
+with the validator; simplifying things even further.</p>
+<p><a name="BeanValidationPrimer-ValidationConstraints"></a></p>
+<h2 id="validation-constraints">Validation Constraints</h2>
+<p>Constraints are a fundamental component of bean validation.  Constraints
+can be placed on Java beans and/or fields and properties (collectively
+labeled attributes in JPA terminology) to constrain the data within the
+bean.  A constraint can either be defined using annotations or XML.  The
+bean validation specification defines a small set of constraints that must
+be included with every validation provider.  This small set covers most
+types of simple validation in addition to a powerful regular expression
+based validator.  If the built-in constraints don't fit the bill, you can
+very easily build your own custom validators and matching constraints. 
+Let's start by looking at some simple constraints and then move to creating
+some custom constraints.</p>
+<p><a name="BeanValidationPrimer-ConstraininganEntity"></a></p>
+<h2 id="constraining-an-entity">Constraining an Entity</h2>
+<p>For the purposes of an example, let's start building the JPA domain model
+for a digital image storage system. For the sake of simplicity, we'll start
+with a simple entity "Image".  An <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/model/Image.java">Image</a>
+ has an ID, image type, file name, and image data.  Our system has a
+requirement that the image type must be specified and the image file name
+must include a valid JPEG or GIF extension.  The code below shows the
+annotated Image entity with some built-in bean validation constraints
+applied.</p>
+<div class="codehilite"><pre><span class="nb">package</span> <span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">openjpa</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">gallery</span><span class="o">.</span><span class="n">model</span><span class="p">;</span>
+
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">persistence</span><span class="o">.</span><span class="n">Entity</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">persistence</span><span class="o">.</span><span class="n">EnumType</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">persistence</span><span class="o">.</span><span class="n">Enumerated</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">persistence</span><span class="o">.</span><span class="n">GeneratedValue</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">persistence</span><span class="o">.</span><span class="n">Id</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">validation</span><span class="o">.</span><span class="n">constraints</span><span class="o">.</span><span class="n">NotNull</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">validation</span><span class="o">.</span><span class="n">constraints</span><span class="o">.</span><span class="n">Pattern</span><span class="p">;</span>
+
+<span class="nv">@Entity</span>
+<span class="n">public</span> <span class="n">class</span> <span class="n">Image</span> <span class="p">{</span>
+
+    <span class="n">private</span> <span class="n">long</span> <span class="n">id</span><span class="p">;</span>
+    <span class="n">private</span> <span class="n">ImageType</span> <span class="n">type</span><span class="p">;</span>
+    <span class="n">private</span> <span class="n">String</span> <span class="n">fileName</span><span class="p">;</span>
+    <span class="n">private</span> <span class="n">byte</span><span class="o">[]</span> <span class="n">data</span><span class="p">;</span>
+
+    <span class="nv">@Id</span>
+    <span class="nv">@GeneratedValue</span>
+    <span class="n">public</span> <span class="n">long</span> <span class="n">getId</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">id</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">setId</span><span class="p">(</span><span class="n">long</span> <span class="n">id</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="n">id</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="nv">@NotNull</span><span class="p">(</span><span class="n">message</span><span class="o">=</span><span class="s">&quot;Image type must be specified.&quot;</span><span class="p">)</span>
+    <span class="nv">@Enumerated</span><span class="p">(</span><span class="n">EnumType</span><span class="o">.</span><span class="n">STRING</span><span class="p">)</span>
+    <span class="n">public</span> <span class="n">ImageType</span> <span class="n">getType</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">type</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">setType</span><span class="p">(</span><span class="n">ImageType</span> <span class="n">type</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">type</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="nv">@Pattern</span><span class="p">(</span><span class="n">regexp</span> <span class="o">=</span> <span class="s">&quot;.*\\.jpg|.*\\.jpeg|.*\\.gif&quot;</span><span class="p">,</span>
+             <span class="n">message</span><span class="o">=</span><span class="s">&quot;Only images of type JPEG or GIF are supported.&quot;</span><span class="p">)</span>
+    <span class="n">public</span> <span class="n">String</span> <span class="n">getFileName</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">fileName</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">setFileName</span><span class="p">(</span><span class="n">String</span> <span class="n">fileName</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">fileName</span> <span class="o">=</span> <span class="n">fileName</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">byte</span><span class="o">[]</span> <span class="n">getData</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">data</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">setData</span><span class="p">(</span><span class="n">byte</span><span class="o">[]</span> <span class="n">data</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="p">;</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>The <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/model/Image.java">Image</a>
+ class uses two built in constraints @NotNull and @Pattern. The @NotNull
+constraint ensures that an <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/ImageType.java">ImageType</a>
+ is specified and @Pattern constraint uses regular expression pattern
+matching to ensure the image file name is suffixed with a supported image
+format.  Each constraint has corresponding validation logic that gets
+executed at runtime when the Image entity is validated.  If either
+constraint is not met, the JPA provider will throw a
+ConstraintViolationException with the defined message.  The <a href="http://jcp.org/en/jsr/detail?id=303">JSR-303 specification</a>
+ also makes provisions for the use of a variable within the message
+attribute.  The variable references a keyed message in a resource bundle. 
+That allows for environment specific messages and localization of messages.
+ See the <a href="http://jcp.org/en/jsr/detail?id=303">JSR-303 specification</a>
+, section 4.1.3 for additional details regarding the customization and
+localization of messages.</p>
+<p><a name="BeanValidationPrimer-CustomConstraintsandValidators"></a></p>
+<h2 id="custom-constraints-and-validators">Custom Constraints and Validators</h2>
+<p>If the built-in constraints do not meet your needs, you can create your own
+custom validators and constraints.  In our previous example, the Image
+entity used the @Pattern constraint to validate the file name of the image.
+ However, it did no constraint checking on the actual image data itself.  A
+pattern-based constraint could potentially be used, but this is rather
+inflexible and will get messy.  A custom constraint and validator provides
+a more robust and flexible solution.  First, let's create a custom method
+level constraint annotation named <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/constraint/ImageContent.java">ImageContent</a>.</p>
+<div class="codehilite"><pre><span class="x">package org.apache.openjpa.example.gallery.constraint;</span>
+
+<span class="x">import java.lang.annotation.Documented;</span>
+<span class="x">import java.lang.annotation.Retention;</span>
+<span class="x">import java.lang.annotation.Target;</span>
+<span class="x">import static java.lang.annotation.ElementType.METHOD;</span>
+<span class="x">import static java.lang.annotation.ElementType.FIELD;</span>
+<span class="x">import static java.lang.annotation.RetentionPolicy.RUNTIME;</span>
+
+<span class="x">import javax.validation.Constraint;</span>
+<span class="x">import javax.validation.Payload;</span>
+
+<span class="x">import org.apache.openjpa.example.gallery.model.ImageType;</span>
+
+<span class="x">@Documented</span>
+<span class="x">@Constraint(validatedBy = ImageContentValidator.class)</span>
+<span class="x">@Target({ METHOD, FIELD })</span>
+<span class="x">@Retention(RUNTIME)</span>
+<span class="x">public @interface ImageContent {</span>
+<span class="x">    String message() default &quot;Image data is not a supported format.&quot;;</span>
+<span class="x">    Class</span><span class="cp">&lt;?</span><span class="o">&gt;</span><span class="p">[]</span> <span class="nx">groups</span><span class="p">()</span> <span class="k">default</span> <span class="p">{};</span>
+    <span class="nx">Class</span><span class="o">&lt;?</span> <span class="k">extends</span> <span class="nx">Payload</span><span class="o">&gt;</span><span class="p">[]</span> <span class="nx">payload</span><span class="p">()</span> <span class="k">default</span> <span class="p">{};</span>
+    <span class="nx">ImageType</span><span class="p">[]</span> <span class="nx">value</span><span class="p">()</span> <span class="k">default</span> <span class="p">{</span> <span class="nx">ImageType</span><span class="o">.</span><span class="nx">GIF</span><span class="p">,</span> <span class="nx">ImageType</span><span class="o">.</span><span class="nx">JPEG</span> <span class="p">};</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Now, let's create the validator class, <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/constraint/ImageContentValidator.java">ImageContentValidator</a>
+.  The logic within this validator gets executed by validation provider
+when the constraint is validated.  Notice, the validator class is bound to
+the constraint annotation via the validatedBy attribute on the @Constraint
+annotation.</p>
+<div class="codehilite"><pre><span class="nb">package</span> <span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">openjpa</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">gallery</span><span class="o">.</span><span class="n">constraint</span><span class="p">;</span>
+
+<span class="nb">import</span> <span class="n">java</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">Arrays</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">java</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">List</span><span class="p">;</span>
+
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">validation</span><span class="o">.</span><span class="n">ConstraintValidator</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">validation</span><span class="o">.</span><span class="n">ConstraintValidatorContext</span><span class="p">;</span>
+
+<span class="nb">import</span> <span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">openjpa</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">gallery</span><span class="o">.</span><span class="n">model</span><span class="o">.</span><span class="n">ImageType</span><span class="p">;</span>
+
+<span class="o">/**</span>
+ <span class="o">*</span> <span class="n">Simple</span> <span class="n">check</span> <span class="n">that</span> <span class="n">file</span> <span class="nb">format</span> <span class="n">is</span> <span class="n">of</span> <span class="n">a</span> <span class="n">supported</span> <span class="n">type</span>
+ <span class="o">*/</span>
+<span class="n">public</span> <span class="n">class</span> <span class="n">ImageContentValidator</span> <span class="n">implements</span> <span class="n">ConstraintValidator</span><span class="o">&lt;</span><span class="n">ImageContent</span><span class="p">,</span> <span class="n">byte</span><span class="o">[]</span> <span class="p">{</span>
+    <span class="n">private</span> <span class="n">List</span><span class="sr">&lt;ImageType&gt;</span> <span class="n">allowedTypes</span> <span class="o">=</span> <span class="n">null</span><span class="p">;</span>
+    <span class="o">/**</span>
+     <span class="o">*</span> <span class="n">Configure</span> <span class="n">the</span> <span class="n">constraint</span> <span class="n">validator</span> <span class="n">based</span> <span class="n">on</span> <span class="n">the</span> <span class="n">image</span>
+     <span class="o">*</span> <span class="n">types</span> <span class="n">it</span> <span class="n">should</span> <span class="n">support</span><span class="o">.</span>
+     <span class="o">*</span> <span class="nv">@param</span> <span class="n">constraint</span> <span class="n">the</span> <span class="n">constraint</span> <span class="n">definition</span>
+     <span class="o">*/</span>
+    <span class="n">public</span> <span class="n">void</span> <span class="n">initialize</span><span class="p">(</span><span class="n">ImageContent</span> <span class="n">constraint</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">allowedTypes</span> <span class="o">=</span> <span class="n">Arrays</span><span class="o">.</span><span class="n">asList</span><span class="p">(</span><span class="n">constraint</span><span class="o">.</span><span class="n">value</span><span class="p">());</span>
+    <span class="p">}</span>
+
+    <span class="o">/**</span>
+     <span class="o">*</span> <span class="n">Validate</span> <span class="n">a</span> <span class="n">specified</span> <span class="n">value</span><span class="o">.</span>
+     <span class="o">*/</span>
+    <span class="n">public</span> <span class="n">boolean</span> <span class="n">isValid</span><span class="p">(</span><span class="n">byte</span><span class="o">[]</span> <span class="n">value</span><span class="p">,</span> <span class="n">ConstraintValidatorContext</span> <span class="n">context</span><span class="p">)</span> <span class="p">{</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">value</span> <span class="o">==</span> <span class="n">null</span><span class="p">)</span> <span class="p">{</span>
+            <span class="k">return</span> <span class="n">false</span><span class="p">;</span>
+        <span class="p">}</span>
+        <span class="sr">//</span> <span class="n">Verify</span> <span class="n">the</span> <span class="n">GIF</span> <span class="n">header</span> <span class="n">is</span> <span class="n">either</span> <span class="n">GIF87</span> <span class="ow">or</span> <span class="n">GIF89</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">allowedTypes</span><span class="o">.</span><span class="n">contains</span><span class="p">(</span><span class="n">ImageType</span><span class="o">.</span><span class="n">GIF</span><span class="p">))</span> <span class="p">{</span>
+            <span class="n">String</span> <span class="n">gifHeader</span> <span class="o">=</span> <span class="k">new</span> <span class="n">String</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">6</span><span class="p">);</span>
+            <span class="k">if</span> <span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="nb">length</span> <span class="o">&gt;=</span> <span class="mi">6</span> <span class="o">&amp;&amp;</span>
+            <span class="p">(</span><span class="n">gifHeader</span><span class="o">.</span><span class="n">equalsIgnoreCase</span><span class="p">(</span><span class="s">&quot;GIF87a&quot;</span><span class="p">)</span> <span class="o">||</span>
+             <span class="n">gifHeader</span><span class="o">.</span><span class="n">equalsIgnoreCase</span><span class="p">(</span><span class="s">&quot;GIF89a&quot;</span><span class="p">)))</span> <span class="p">{</span>
+            <span class="k">return</span> <span class="n">true</span><span class="p">;</span>
+            <span class="p">}</span>
+        <span class="p">}</span>
+        <span class="sr">//</span> <span class="n">Verify</span> <span class="n">the</span> <span class="n">JPEG</span> <span class="n">begins</span> <span class="n">with</span> <span class="n">SOI</span> <span class="o">&amp;</span> <span class="n">ends</span> <span class="n">with</span> <span class="n">EOI</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">allowedTypes</span><span class="o">.</span><span class="n">contains</span><span class="p">(</span><span class="n">ImageType</span><span class="o">.</span><span class="n">JPEG</span><span class="p">))</span> <span class="p">{</span>
+            <span class="k">if</span> <span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="nb">length</span> <span class="o">&gt;=</span> <span class="mi">4</span> <span class="o">&amp;&amp;</span>
+                <span class="n">value</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0xff</span> <span class="o">&amp;&amp;</span> <span class="n">value</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0xd8</span> <span class="o">&amp;&amp;</span>
+                <span class="n">value</span><span class="p">[</span><span class="n">value</span><span class="o">.</span><span class="nb">length</span> <span class="o">-</span> <span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0xff</span> <span class="o">&amp;&amp;</span>
+                <span class="n">value</span><span class="p">[</span><span class="n">value</span><span class="o">.</span><span class="nb">length</span> <span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0xd9</span><span class="p">)</span> <span class="p">{</span>
+                <span class="k">return</span> <span class="n">true</span><span class="p">;</span>
+            <span class="p">}</span>
+        <span class="p">}</span>
+        <span class="sr">//</span> <span class="n">Unknown</span> <span class="n">file</span> <span class="nb">format</span>
+        <span class="k">return</span> <span class="n">false</span><span class="p">;</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Finally, let's apply the new constraint to the getData() method on our
+Image class.</p>
+<div class="codehilite"><pre>    <span class="nv">@ImageContent</span>
+    <span class="n">public</span> <span class="n">byte</span><span class="o">[]</span> <span class="n">getData</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">data</span><span class="p">;</span>
+    <span class="p">}</span>
+</pre></div>
+
+
+<p>When validation of the "data" attribute occurs, the isValid() method in our <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/constraint/ImageContentValidator.java">ImageContentValidator</a>
+ will fire.  This method contains logic for performing simple validation of
+ the format of the binary image data.  A potentially overlooked feature in
+the <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/constraint/ImageContentValidator.java">ImageContentValidator</a>
+ is that it can also validate for a specific image type.  By definition, it
+accepts for JPEG or GIF formats, but it can also validate for a specific
+format.  For example, by changing the annotation to:</p>
+<div class="codehilite"><pre>    <span class="nv">@ImageContent</span><span class="p">(</span><span class="n">ImageType</span><span class="o">.</span><span class="n">JPEG</span><span class="p">)</span>
+    <span class="n">public</span> <span class="n">byte</span><span class="o">[]</span> <span class="n">getData</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">data</span><span class="p">;</span>
+    <span class="p">}</span>
+</pre></div>
+
+
+<p>instructs the validator to only permit image data with valid JPEG content.</p>
+<p><a name="BeanValidationPrimer-Type-levelConstraints"></a></p>
+<h2 id="type-level-constraints">Type-level Constraints</h2>
+<p>The examples thus far have shown the use of validation constraints on
+individual attributes.  That is sufficient in many cases, but validation
+logic often needs to consider combinations of attributes when validating an
+entity.  For example, the constraints applied to the Image entity validate
+that an image type is set (not null), the extension on the image file name
+are of a supported type, and the data format is correct for the indicated
+type. But, for example, it will not collectively validate that a file named
+"img0.gif" is of type GIF and the format of the data is for a valid GIF
+image.  There are several options to provide collective validation.  One
+option is to create subclasses of Image, JPEGImage and GIFImage, with
+constraints geared for each of these types.  Another, less invasive and
+simpler option is a type-level constraint.  Let's modify our Image class to
+use a custom type-level constraint.  Here is the updated Image entity with
+the new type-level constraint.</p>
+<div class="codehilite"><pre><span class="nb">package</span> <span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">openjpa</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">gallery</span><span class="o">.</span><span class="n">model</span><span class="p">;</span>
+
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">persistence</span><span class="o">.</span><span class="n">Embedded</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">persistence</span><span class="o">.</span><span class="n">Entity</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">persistence</span><span class="o">.</span><span class="n">EnumType</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">persistence</span><span class="o">.</span><span class="n">Enumerated</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">persistence</span><span class="o">.</span><span class="n">GeneratedValue</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">persistence</span><span class="o">.</span><span class="n">Id</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">persistence</span><span class="o">.</span><span class="n">ManyToOne</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">validation</span><span class="o">.</span><span class="n">Valid</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">validation</span><span class="o">.</span><span class="n">constraints</span><span class="o">.</span><span class="n">NotNull</span><span class="p">;</span>
+
+<span class="nb">import</span> <span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">openjpa</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">gallery</span><span class="o">.</span><span class="n">constraint</span><span class="o">.</span><span class="n">ImageConstraint</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">openjpa</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">gallery</span><span class="o">.</span><span class="n">constraint</span><span class="o">.</span><span class="n">SequencedImageGroup</span><span class="p">;</span>
+
+<span class="nv">@Entity</span>
+<span class="nv">@ImageConstraint</span><span class="p">(</span><span class="n">groups</span><span class="o">=</span><span class="n">ImageGroup</span><span class="o">.</span><span class="n">class</span><span class="p">)</span>
+<span class="n">public</span> <span class="n">class</span> <span class="n">Image</span> <span class="p">{</span>
+
+    <span class="n">private</span> <span class="n">long</span> <span class="n">id</span><span class="p">;</span>
+    <span class="n">private</span> <span class="n">ImageType</span> <span class="n">type</span><span class="p">;</span>
+    <span class="n">private</span> <span class="n">String</span> <span class="n">fileName</span><span class="p">;</span>
+    <span class="n">private</span> <span class="n">byte</span><span class="o">[]</span> <span class="n">data</span><span class="p">;</span>
+
+    <span class="nv">@Id</span>
+    <span class="nv">@GeneratedValue</span>
+    <span class="n">public</span> <span class="n">long</span> <span class="n">getId</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">id</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">setId</span><span class="p">(</span><span class="n">long</span> <span class="n">id</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="n">id</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="nv">@NotNull</span><span class="p">(</span><span class="n">message</span><span class="o">=</span><span class="s">&quot;Image type must be specified.&quot;</span><span class="p">)</span>
+    <span class="nv">@Enumerated</span><span class="p">(</span><span class="n">EnumType</span><span class="o">.</span><span class="n">STRING</span><span class="p">)</span>
+    <span class="n">public</span> <span class="n">ImageType</span> <span class="n">getType</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">type</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">setType</span><span class="p">(</span><span class="n">ImageType</span> <span class="n">type</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">type</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="nv">@NotNull</span><span class="p">(</span><span class="n">message</span><span class="o">=</span><span class="s">&quot;Image file name must not be null.&quot;</span><span class="p">)</span>
+    <span class="n">public</span> <span class="n">String</span> <span class="n">getFileName</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">fileName</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">setFileName</span><span class="p">(</span><span class="n">String</span> <span class="n">fileName</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">fileName</span> <span class="o">=</span> <span class="n">fileName</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="nv">@NotNull</span><span class="p">(</span><span class="n">message</span><span class="o">=</span><span class="s">&quot;Image data must not be null.&quot;</span><span class="p">)</span>
+    <span class="n">public</span> <span class="n">byte</span><span class="o">[]</span> <span class="n">getData</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">data</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">setData</span><span class="p">(</span><span class="n">byte</span><span class="o">[]</span> <span class="n">data</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="p">;</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Notice that the @Pattern and @ImageContent were replaced by @NotNull
+constraints.  The new class level constraint will perform the duties
+previously performed by @Pattern and @ImageContent.  The @NotNull
+constraints have been added as a first level check.  If these constraints
+succeed, the type level validator @ImageConstraint will fire, providing
+complex validation.  Sequenced validation is provided using validation
+groups and group sequences.  These concepts will be explained shortly.</p>
+<p>Here is the code for the new <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/constraint/ImageConstraint.java">ImageConstraint</a>
+ annotation:</p>
+<div class="codehilite"><pre><span class="x">package org.apache.openjpa.example.gallery.constraint;</span>
+
+<span class="x">import java.lang.annotation.Documented;</span>
+<span class="x">import java.lang.annotation.Retention;</span>
+<span class="x">import java.lang.annotation.Target;</span>
+<span class="x">import static java.lang.annotation.ElementType.TYPE;</span>
+<span class="x">import static java.lang.annotation.RetentionPolicy.RUNTIME;</span>
+
+<span class="x">import javax.validation.Constraint;</span>
+<span class="x">import javax.validation.Payload;</span>
+
+<span class="x">import org.apache.openjpa.example.gallery.model.ImageType;</span>
+
+<span class="x">@Documented</span>
+<span class="x">@Constraint(validatedBy = ImageValidator.class)</span>
+<span class="x">@Target({ TYPE })</span>
+<span class="x">@Retention(RUNTIME)</span>
+<span class="x">public @interface ImageConstraint {</span>
+<span class="x">    String message() default &quot;Image data is not a supported format.&quot;;</span>
+<span class="x">    Class</span><span class="cp">&lt;?</span><span class="o">&gt;</span><span class="p">[]</span> <span class="nx">groups</span><span class="p">()</span> <span class="k">default</span> <span class="p">{};</span>
+    <span class="nx">Class</span><span class="o">&lt;?</span> <span class="k">extends</span> <span class="nx">Payload</span><span class="o">&gt;</span><span class="p">[]</span> <span class="nx">payload</span><span class="p">()</span> <span class="k">default</span> <span class="p">{};</span>
+    <span class="nx">ImageType</span><span class="p">[]</span> <span class="nx">value</span><span class="p">()</span> <span class="k">default</span> <span class="p">{</span> <span class="nx">ImageType</span><span class="o">.</span><span class="nx">GIF</span><span class="p">,</span> <span class="nx">ImageType</span><span class="o">.</span><span class="nx">JPEG</span> <span class="p">};</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Unlike the <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/constraint/ImageContent.java">ImageContent</a>
+ constraint, <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/constraint/ImageConstraint.java">ImageConstraint</a>
+ is targeted for a TYPE.  This allows this annotation to be applied at a
+type level (class or interface).  This constraint has a new validator
+class, <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/constraint/ImageValidator.java">ImageValidator</a>
+.</p>
+<div class="codehilite"><pre><span class="nb">package</span> <span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">openjpa</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">gallery</span><span class="o">.</span><span class="n">constraint</span><span class="p">;</span>
+
+<span class="nb">import</span> <span class="n">java</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">Arrays</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">java</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">List</span><span class="p">;</span>
+
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">validation</span><span class="o">.</span><span class="n">ConstraintValidator</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">validation</span><span class="o">.</span><span class="n">ConstraintValidatorContext</span><span class="p">;</span>
+
+<span class="nb">import</span> <span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">openjpa</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">gallery</span><span class="o">.</span><span class="n">model</span><span class="o">.</span><span class="n">Image</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">openjpa</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">gallery</span><span class="o">.</span><span class="n">model</span><span class="o">.</span><span class="n">ImageType</span><span class="p">;</span>
+
+<span class="o">/**</span>
+ <span class="o">*</span> <span class="n">Simple</span> <span class="n">check</span> <span class="n">that</span> <span class="n">an</span> <span class="n">Image</span> <span class="n">is</span> <span class="n">consistent</span> <span class="n">in</span> <span class="n">type</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="ow">and</span> <span class="nb">format</span><span class="o">.</span>
+ <span class="o">*/</span>
+<span class="n">public</span> <span class="n">class</span> <span class="n">ImageValidator</span> <span class="n">implements</span> <span class="n">ConstraintValidator</span><span class="sr">&lt;ImageConstraint,Image&gt;</span> <span class="p">{</span>
+    <span class="n">private</span> <span class="n">List</span><span class="sr">&lt;ImageType&gt;</span> <span class="n">allowedTypes</span> <span class="o">=</span> <span class="n">null</span><span class="p">;</span>
+    <span class="o">/**</span>
+     <span class="o">*</span> <span class="n">Configure</span> <span class="n">the</span> <span class="n">constraint</span> <span class="n">validator</span> <span class="n">based</span> <span class="n">on</span> <span class="n">the</span> <span class="n">image</span>
+     <span class="o">*</span> <span class="n">types</span> <span class="n">it</span> <span class="n">should</span> <span class="n">support</span><span class="o">.</span>
+     <span class="o">*</span> <span class="nv">@param</span> <span class="n">constraint</span> <span class="n">the</span> <span class="n">constraint</span> <span class="n">definition</span>
+     <span class="o">*/</span>
+    <span class="n">public</span> <span class="n">void</span> <span class="n">initialize</span><span class="p">(</span><span class="n">ImageConstraint</span> <span class="n">constraint</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">allowedTypes</span> <span class="o">=</span> <span class="n">Arrays</span><span class="o">.</span><span class="n">asList</span><span class="p">(</span><span class="n">constraint</span><span class="o">.</span><span class="n">value</span><span class="p">());</span>
+    <span class="p">}</span>
+
+    <span class="o">/**</span>
+     <span class="o">*</span> <span class="n">Validate</span> <span class="n">a</span> <span class="n">specified</span> <span class="n">value</span><span class="o">.</span>
+     <span class="o">*/</span>
+    <span class="n">public</span> <span class="n">boolean</span> <span class="n">isValid</span><span class="p">(</span><span class="n">Image</span> <span class="n">value</span><span class="p">,</span> <span class="n">ConstraintValidatorContext</span> <span class="n">context</span><span class="p">)</span> <span class="p">{</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">value</span> <span class="o">==</span> <span class="n">null</span><span class="p">)</span> <span class="p">{</span>
+            <span class="k">return</span> <span class="n">true</span><span class="p">;</span>
+        <span class="p">}</span>
+
+        <span class="sr">//</span> <span class="n">All</span> <span class="n">these</span> <span class="n">fields</span> <span class="n">will</span> <span class="n">be</span> <span class="n">pre</span><span class="o">-</span><span class="n">validated</span> <span class="n">with</span> <span class="nv">@NotNull</span> <span class="n">constraints</span>
+        <span class="sr">//</span> <span class="n">so</span> <span class="n">they</span> <span class="n">are</span> <span class="n">safe</span> <span class="n">to</span> <span class="k">use</span> <span class="n">without</span> <span class="n">null</span> <span class="n">checks</span><span class="o">.</span>
+        <span class="n">byte</span><span class="o">[]</span> <span class="n">data</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">getData</span><span class="p">();</span>
+        <span class="n">String</span> <span class="n">fileName</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">getFileName</span><span class="p">();</span>
+        <span class="n">ImageType</span> <span class="n">type</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">getType</span><span class="p">();</span>
+
+        <span class="sr">//</span> <span class="n">Verify</span> <span class="n">the</span> <span class="n">GIF</span> <span class="n">type</span> <span class="n">is</span> <span class="n">correct</span><span class="p">,</span> <span class="n">has</span> <span class="n">the</span> <span class="n">correct</span> <span class="n">extension</span> <span class="ow">and</span>
+        <span class="sr">//</span> <span class="n">the</span> <span class="n">data</span> <span class="n">header</span> <span class="n">is</span> <span class="n">either</span> <span class="n">GIF87</span> <span class="ow">or</span> <span class="n">GIF89</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">allowedTypes</span><span class="o">.</span><span class="n">contains</span><span class="p">(</span><span class="n">ImageType</span><span class="o">.</span><span class="n">GIF</span><span class="p">)</span> <span class="o">&amp;&amp;</span>
+            <span class="n">type</span> <span class="o">==</span> <span class="n">ImageType</span><span class="o">.</span><span class="n">GIF</span> <span class="o">&amp;&amp;</span>
+            <span class="n">fileName</span><span class="o">.</span><span class="n">endsWith</span><span class="p">(</span><span class="s">&quot;.gif&quot;</span><span class="p">))</span> <span class="p">{</span>
+            <span class="k">if</span> <span class="p">(</span><span class="n">data</span> <span class="o">!=</span> <span class="n">null</span> <span class="o">&amp;&amp;</span> <span class="n">data</span><span class="o">.</span><span class="nb">length</span> <span class="o">&gt;=</span> <span class="mi">6</span><span class="p">)</span> <span class="p">{</span>
+                <span class="n">String</span> <span class="n">gifHeader</span> <span class="o">=</span> <span class="k">new</span> <span class="n">String</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">6</span><span class="p">);</span>
+                <span class="k">if</span> <span class="p">(</span><span class="n">gifHeader</span><span class="o">.</span><span class="n">equalsIgnoreCase</span><span class="p">(</span><span class="s">&quot;GIF87a&quot;</span><span class="p">)</span> <span class="o">||</span>
+                     <span class="n">gifHeader</span><span class="o">.</span><span class="n">equalsIgnoreCase</span><span class="p">(</span><span class="s">&quot;GIF89a&quot;</span><span class="p">))</span> <span class="p">{</span>
+                    <span class="k">return</span> <span class="n">true</span><span class="p">;</span>
+                <span class="p">}</span>
+            <span class="p">}</span>
+        <span class="p">}</span>
+        <span class="sr">//</span> <span class="n">Verify</span> <span class="n">the</span> <span class="n">JPEG</span> <span class="n">type</span> <span class="n">is</span> <span class="n">correct</span><span class="p">,</span> <span class="n">has</span> <span class="n">the</span> <span class="n">correct</span> <span class="n">extension</span> <span class="ow">and</span>
+        <span class="sr">//</span> <span class="n">the</span> <span class="n">data</span> <span class="n">begins</span> <span class="n">with</span> <span class="n">SOI</span> <span class="o">&amp;</span> <span class="n">ends</span> <span class="n">with</span> <span class="n">EOI</span> <span class="n">markers</span>
+        <span class="k">if</span> <span class="p">(</span><span class="n">allowedTypes</span><span class="o">.</span><span class="n">contains</span><span class="p">(</span><span class="n">ImageType</span><span class="o">.</span><span class="n">JPEG</span><span class="p">)</span> <span class="o">&amp;&amp;</span>
+            <span class="n">value</span><span class="o">.</span><span class="n">getType</span><span class="p">()</span> <span class="o">==</span> <span class="n">ImageType</span><span class="o">.</span><span class="n">JPEG</span> <span class="o">&amp;&amp;</span>
+            <span class="p">(</span><span class="n">fileName</span><span class="o">.</span><span class="n">endsWith</span><span class="p">(</span><span class="s">&quot;.jpg&quot;</span><span class="p">)</span> <span class="o">||</span>
+             <span class="n">fileName</span><span class="o">.</span><span class="n">endsWith</span><span class="p">(</span><span class="s">&quot;.jpeg&quot;</span><span class="p">)))</span> <span class="p">{</span>
+            <span class="k">if</span> <span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="nb">length</span> <span class="o">&gt;=</span> <span class="mi">4</span> <span class="o">&amp;&amp;</span>
+                <span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0xff</span> <span class="o">&amp;&amp;</span> <span class="n">data</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0xd8</span> <span class="o">&amp;&amp;</span>
+                <span class="n">data</span><span class="p">[</span><span class="n">data</span><span class="o">.</span><span class="nb">length</span> <span class="o">-</span> <span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0xff</span> <span class="o">&amp;&amp;</span>
+                <span class="n">data</span><span class="p">[</span><span class="n">data</span><span class="o">.</span><span class="nb">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0xd9</span><span class="p">)</span> <span class="p">{</span>
+                <span class="k">return</span> <span class="n">true</span><span class="p">;</span>
+            <span class="p">}</span>
+        <span class="p">}</span>
+        <span class="sr">//</span> <span class="n">Unknown</span> <span class="n">file</span> <span class="nb">format</span>
+        <span class="k">return</span> <span class="n">false</span><span class="p">;</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>One thing that must be considered in a JPA environment is the load state of
+the attributes of an entity when doing type-level validation.  Simply
+accessing attributes can have some side effects.  If the attribute is
+marked LAZY fetch it may get loaded in order to perform validation.  If the
+attribute is not loaded and cannot be loaded (for several reasons, most
+likely due to detachment) you'll be validating  inconsistent data.  The JPA
+2.0 specification provides a utility interface to help in these situations.
+ It can be obtained statically so squirreling away a copy of the JPA entity
+manager is not necessary.  Here is an example of how PersistenceUtil could
+be used in the ImageValidator.</p>
+<div class="codehilite"><pre>    <span class="n">byte</span><span class="o">[]</span> <span class="n">data</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">getData</span><span class="p">();</span>
+    <span class="n">PersistenceUtil</span> <span class="n">putil</span> <span class="o">=</span> <span class="n">Persistence</span><span class="o">.</span><span class="n">getPersistenceUtil</span><span class="p">();</span>
+    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">putil</span><span class="o">.</span><span class="n">isLoaded</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="s">&quot;data&quot;</span><span class="p">))</span> <span class="p">{</span>
+        <span class="sr">//</span> <span class="n">don</span><span class="err">&#39;</span><span class="n">t</span> <span class="n">validate</span> <span class="n">the</span> <span class="n">data</span>
+    <span class="p">}</span>
+</pre></div>
+
+
+<p><a name="BeanValidationPrimer-TheCompleteDomainModel"></a></p>
+<h3 id="the-complete-domain-model">The Complete Domain Model</h3>
+<p>Now that some of the basics of bean validation are covered, let's finish up
+the domain model for our simple application and then get into JPA specifics
+through an example.</p>
+<p><img alt="ig_domain_model.gif" src="images/ig_domain_model.gif" /></p>
+<p>The persistent types <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/model/Album.java">Album</a>
+, <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/model/Creator.java">Creator</a>
+, and <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/model/Location.java">Location</a>
+ are new to the domain model.  An Album entity contains a reference to
+collection of its Image entities.  The Creator entity contains a reference
+to the Album album entities the image Creator contributed to and a
+reference to the Image entities they've created.  This provides full
+navigational capabilities to and from each of the entities in the domain. 
+An embeddable, Location, has been added to Image to allow location
+information to be stored along with the Image.</p>
+<p>The Album and Creator entities have a few built-in constraints and are
+pretty run of the mill.  The embeddable <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/model/Location.java">Location</a>
+ is a bit more interesting in that it demonstrates the use of the @Valid
+annotation to validate embedded objects.  In order to embed location into
+an image a new field and corresponding persistent properties were added to
+the Image class:</p>
+<div class="codehilite"><pre>    <span class="n">private</span> <span class="n">Location</span> <span class="n">location</span><span class="p">;</span>
+
+    <span class="nv">@Valid</span>
+    <span class="nv">@Embedded</span>
+    <span class="n">public</span> <span class="n">Location</span> <span class="n">getLocation</span><span class="p">()</span> <span class="p">{</span>
+        <span class="k">return</span> <span class="n">location</span><span class="p">;</span>
+    <span class="p">}</span>
+
+    <span class="n">public</span> <span class="n">void</span> <span class="n">setLocation</span><span class="p">(</span><span class="n">Location</span> <span class="n">location</span><span class="p">)</span> <span class="p">{</span>
+        <span class="n">this</span><span class="o">.</span><span class="n">location</span> <span class="o">=</span> <span class="n">location</span><span class="p">;</span>
+    <span class="p">}</span>
+</pre></div>
+
+
+<p>Notice the use of the @Valid annotation.  This provides chained validation
+of embeddables within a JPA environment.  Thus, when Image is validated,
+any constraints on the Location it references are also validated.  If
+@Valid was not specified, Location would not get validated.  In a JPA
+environment, chained validation via @Valid is only available for
+embeddables.  Referenced entities and collections of entities are validated
+separately in order to prevent circular validation.</p>
+<p><a name="BeanValidationPrimer-ValidationGroups"></a></p>
+<h2 id="validation-groups">Validation Groups</h2>
+<p>Bean validation uses validation groups to determine what and when
+validation occurs.  There are no special interfaces to implement or
+annotations to apply in order to create a validation group.  A validation
+group is denoted simply by a class definition. However, it is strongly
+recommended that simple interfaces are used.  This is a best practice since
+it makes validation groups more usable in multiple environments.  Whereas,
+if a class or entity definition were used as a validation group, it may
+pollute the object model of another application by bringing in domain
+classes and logic that do not make sense for the application. By default,
+if a validation group or multiple groups is not specified on an individual
+constraint, it will be validated using the
+<strong>javax.validation.groups.Default</strong> group.  Creating a custom group is as
+simple as creating a new interface definition.</p>
+<div class="codehilite"><pre><span class="nb">package</span> <span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">openjpa</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">gallery</span><span class="o">.</span><span class="n">constraint</span><span class="p">;</span>
+
+<span class="n">public</span> <span class="n">interface</span> <span class="n">ImageGroup</span> <span class="p">{</span>
+
+<span class="p">}</span>
+</pre></div>
+
+
+<p>This new <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/constraint/ImageGroup.java">ImageGroup</a>
+ validation group can now be applied to a constraint.</p>
+<div class="codehilite"><pre><span class="nv">@ImageContent</span><span class="p">(</span><span class="n">groups</span><span class="o">=</span><span class="p">{</span><span class="n">Default</span><span class="o">.</span><span class="n">class</span><span class="p">,</span><span class="n">ImageGroup</span><span class="o">.</span><span class="n">class</span><span class="p">})</span>
+<span class="n">public</span> <span class="n">byte</span><span class="o">[]</span> <span class="n">getData</span><span class="p">()</span> <span class="p">{</span>
+    <span class="k">return</span> <span class="n">data</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>This @ImageContent constraint in this example will validate when either or
+both the Default and/or <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/main/java/org/apache/openjpa/example/gallery/constraint/ImageGroup.java">ImageGroup</a>
+ group is/are validated.</p>
+<p>By default there is no order applied or short circuiting behavior when
+validation occurs.  Validation ordering and short circuiting is an
+extremely useful function that can be achieved by defining a group
+sequence.  A group sequence is defined via the @GroupSequence annotation
+with an ordered array of validation groups.  When the group sequence is
+validated, the constraints supplied in its grouping are validated in the
+order they are specified.  In addition, if a constraint within a group
+fails, the groups that follow will not be validated.  This allows
+lightweight validation such as @NotNull or @Size constraints to validate
+before heavyweight constraints.  The Image class uses a group sequence to
+validate its lightweight @NotNull constraints (which use the Default
+validation group) before validating its heavyweight constraint
+@ImageValidator (which validates when the ImageGroup) is validated. 
+Sequenced validation can be accomplished by defining a new validation
+group.</p>
+<div class="codehilite"><pre><span class="nb">package</span> <span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">openjpa</span><span class="o">.</span><span class="n">example</span><span class="o">.</span><span class="n">gallery</span><span class="o">.</span><span class="n">constraint</span><span class="p">;</span>
+
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">validation</span><span class="o">.</span><span class="n">GroupSequence</span><span class="p">;</span>
+<span class="nb">import</span> <span class="n">javax</span><span class="o">.</span><span class="n">validation</span><span class="o">.</span><span class="n">groups</span><span class="o">.</span><span class="n">Default</span><span class="p">;</span>
+
+<span class="nv">@GroupSequence</span><span class="p">({</span><span class="n">Default</span><span class="o">.</span><span class="n">class</span><span class="p">,</span> <span class="n">ImageGroup</span><span class="o">.</span><span class="n">class</span><span class="p">})</span>
+<span class="n">public</span> <span class="n">interface</span> <span class="n">SequencedImageGroup</span> <span class="p">{</span>
+
+<span class="p">}</span>
+</pre></div>
+
+
+<p>This group is then specified during validation.  How to specify which
+groups will be validated in a JPA environment is explained in the sections
+to follow.</p>
+<p><a name="BeanValidationPrimer-JPAIntegration"></a></p>
+<h2 id="jpa-integration">JPA Integration</h2>
+<p>The JPA 2.0 specification makes integration with JSR-303 very simple.  In a
+JSE environment all you need to do is provide the JSR-303 API and a JSR-303
+bean validation provider on your runtime classpath and bean validation is
+enabled by default.  OpenJPA adds one additional caveat.  With OpenJPA you
+must also be using a version 2.0 persistence.xml file.  A version 1.0
+persistence.xml provides no means to configure bean validation.  Requiring
+a version 2.0 persistence.xml prevents a pure JPA 1.0 application from
+incurring the validation startup and runtime costs.  This is important
+given that there is no standard means for a 1.0-based application to
+disable validation.  Besides adding the necessary bean validation jars to
+your classpath, enabling validation in an existing 1.0 application may be
+as simple as modifying the root element of your persistence.xml to:</p>
+<div class="codehilite"><pre><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
+<span class="nt">&lt;persistence</span> <span class="na">xmlns=</span><span class="s">&quot;http://java.sun.com/xml/ns/persistence&quot;</span>
+    <span class="na">xmlns:xsi=</span><span class="s">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span>
+    <span class="na">xsi:schemaLocation=</span><span class="s">&quot;http://java.sun.com/xml/ns/persistence</span>
+<span class="s">    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd&quot;</span>
+    <span class="na">version=</span><span class="s">&quot;2.0&quot;</span> <span class="nt">&gt;</span>
+...
+<span class="nt">&lt;/persistence&gt;</span>
+</pre></div>
+
+
+<table class="info"><tr>
+  <td valign="top"><img src="images/information.gif" width="16" height="16" border="0">
+  <td><b>**NOTE**</b><br/>
+While the JPA 2.0 specification is backward compatible
+with JPA 1.0, there are some OpenJPA specific extensions that are not.  By
+switching to a 2.0 persistence.xml, in some cases you may need to specify
+compatibility flags in order to get OpenJPA 1.0 behavior.  See the [migration considerations](http://openjpa.apache.org/builds/latest/docs/manual/migration_considerations.html)
+section of the [OpenJPA 2.x manual](http://openjpa.apache.org/builds/latest/docs/manual/main.html)
+for additional information.
+</tr></table>
+
+<p><a name="BeanValidationPrimer-ValidationModes"></a></p>
+<h3 id="validation-modes">Validation Modes</h3>
+<p>Bean validation provides three modes of operation within the JPA
+environment: <em>auto</em>, <em>callback</em>, and <em>none</em>.  As you may have guessed,
+<em>none</em> disables bean validation for a particular persistence unit.  The
+<em>auto</em> mode, which is the default, enables bean validation if a validation
+provider is available within the classpath.  When <em>callback</em> mode is
+specified, a bean validation provider must be available for use by the JPA
+provider.  If not, the JPA provider will throw an exception upon
+instantiation of a new JPA entity manager factory.  While <em>auto</em> mode
+simplifies deployment, it can lead to problems if validation is
+unexpectedly not taking place due to a configuration problem.  It is a good
+practice to use either <em>none</em> or <em>callback</em> mode explicitly in order to get
+consistent behavior.  In addition, if <em>none</em> is specified, OpenJPA will do
+optimization at startup and will not attempt to perform unexpected
+validation.  Explicitly disabling validation is especially important in a
+JEE6 environment where the container is mandated to provide a validation
+provider.  Thus, unless specified, a JPA 2.0 app running in a container
+will have validation enabled.  This will add additional processing during
+lifecycle events. We'll get to lifecycle events shortly.</p>
+<p>There are two means to configure validation modes in JPA 2.0.  Perhaps the
+simplest is to add a validation-mode element to your persistence.xml with
+the desired validation mode.</p>
+<div class="codehilite"><pre>    <span class="nt">&lt;persistence-unit</span> <span class="na">name=</span><span class="s">&quot;auto-validation&quot;</span><span class="nt">&gt;</span>
+        ...
+        <span class="c">&lt;!-- Validation modes: AUTO, CALLBACK, NONE --&gt;</span>
+        <span class="nt">&lt;validation-mode&gt;</span>AUTO<span class="nt">&lt;/validation-mode&gt;</span>
+        ...
+    <span class="nt">&lt;/persistence-unit&gt;</span>
+</pre></div>
+
+
+<p>In addition, the validation mode can be configured programmatically by
+specifying the <strong>javax.persistence.validation.mode</strong> property with value
+<em>auto</em>, <em>callback</em>, or <em>none</em> when creating a new JPA entity manager
+factory.</p>
+<div class="codehilite"><pre>    <span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">String</span><span class="o">&gt;</span> <span class="n">props</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HashMap</span><span class="sr">&lt;String,String&gt;</span><span class="p">();</span>
+    <span class="n">props</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="s">&quot;javax.persistence.validation.mode&quot;</span><span class="p">,</span> <span class="s">&quot;callback&quot;</span><span class="p">);</span>
+    <span class="n">EntityManagerFactory</span> <span class="n">emf</span> <span class="o">=</span> 
+        <span class="n">Persistence</span><span class="o">.</span><span class="n">createEntityManagerFactory</span><span class="p">(</span><span class="s">&quot;validation&quot;</span><span class="p">,</span> <span class="n">props</span><span class="p">);</span>
+</pre></div>
+
+
+<p><a name="BeanValidationPrimer-ValidationinJPA"></a></p>
+<h3 id="validation-in-jpa">Validation in JPA</h3>
+<p>We've covered the basics of constraints and validation configuration, now
+on to actually doing some validation within JPA.  Bean validation within
+JPA occurs during JPA's lifecycle event processing.  If enabled, validation
+will occur at the final stage of the PrePersist, PreUpdate, and PreRemove
+lifecycle events.  Validation will occur only after all user defined
+lifecycle events, since some of those events may modify the entity that is
+being validated.   By default, JPA enables validation for the Default
+validation group for PrePersist and PreUpdate lifecycle events.  If you
+need to validate other Validation groups or enable validation for the
+PreRemove event you can specify the validation groups to validate for each
+lifecycle event in the <a href="http://svn.apache.org/repos/asf/openjpa/trunk/openjpa-examples/image-gallery/src/test/resources/META-INF/persistence.xml">persistence.xml</a>
+.</p>
+<div class="codehilite"><pre>   <span class="nt">&lt;persistence-unit</span> <span class="na">name=</span><span class="s">&quot;non-default-validation-groups&quot;</span><span class="nt">&gt;</span>
+    <span class="nt">&lt;class&gt;</span>my.Entity<span class="nt">&lt;/class&gt;</span>
+    <span class="nt">&lt;validation-mode&gt;</span>CALLBACK<span class="nt">&lt;/validation-mode&gt;</span>
+    <span class="nt">&lt;properties&gt;</span>
+        <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;javax.persistence.validation.group.pre-persist&quot;</span>
+            <span class="na">value=</span><span class="s">&quot;org.apache.openjpa.example.gallery.constraint.SequencedImageGroup&quot;</span><span class="nt">/&gt;</span>
+        <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;javax.persistence.validation.group.pre-update&quot;</span>
+            <span class="na">value=</span><span class="s">&quot;org.apache.openjpa.example.gallery.constraint.SequencedImageGroup&quot;</span><span class="nt">/&gt;</span>
+        <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">&quot;javax.persistence.validation.group.pre-remove&quot;</span>
+            <span class="na">value=</span><span class="s">&quot;javax.validation.groups.Default&quot;</span><span class="nt">/&gt;</span>
+    <span class="nt">&lt;/properties&gt;</span>
+<span class="nt">&lt;/persistence-unit&gt;</span>
+</pre></div>
+
+
+<p>Now that we've gone through validation basics and JPA configuration
+options, the validation part is a piece of cake.  In general, you simply
+need to handle validation exceptions that may result from various JPA
+operations.  Here are some simple examples for the persist, update, and
+remove operations.  We'll get to more in-depth exception handling in a
+moment.</p>
+<div class="codehilite"><pre>    <span class="n">EntityManagerFactory</span> <span class="n">emf</span> <span class="o">=</span> 
+        <span class="n">Persistence</span><span class="o">.</span><span class="n">createEntityManagerFactory</span><span class="p">(</span><span class="s">&quot;BeanValidation&quot;</span><span class="p">);</span>
+    <span class="n">EntityManager</span> <span class="n">em</span> <span class="o">=</span> <span class="n">emf</span><span class="o">.</span><span class="n">createEntityManager</span><span class="p">();</span>
+
+    <span class="n">Location</span> <span class="n">loc</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Location</span><span class="p">();</span>
+    <span class="n">loc</span><span class="o">.</span><span class="n">setCity</span><span class="p">(</span><span class="s">&quot;Rochester&quot;</span><span class="p">);</span>
+    <span class="n">loc</span><span class="o">.</span><span class="n">setState</span><span class="p">(</span><span class="s">&quot;MN&quot;</span><span class="p">);</span>
+    <span class="n">loc</span><span class="o">.</span><span class="n">setZipCode</span><span class="p">(</span><span class="s">&quot;55901&quot;</span><span class="p">);</span>
+    <span class="n">loc</span><span class="o">.</span><span class="n">setCountry</span><span class="p">(</span><span class="s">&quot;USA&quot;</span><span class="p">);</span>
+
+    <span class="sr">//</span> <span class="n">Create</span> <span class="n">an</span> <span class="n">Image</span> <span class="n">with</span> <span class="n">non</span><span class="o">-</span><span class="n">matching</span> <span class="n">type</span> <span class="ow">and</span> <span class="n">file</span> <span class="n">extension</span>
+    <span class="n">Image</span> <span class="n">img</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Image</span><span class="p">();</span>
+    <span class="n">img</span><span class="o">.</span><span class="n">setType</span><span class="p">(</span><span class="n">ImageType</span><span class="o">.</span><span class="n">JPEG</span><span class="p">);</span>
+    <span class="n">img</span><span class="o">.</span><span class="n">setFileName</span><span class="p">(</span><span class="s">&quot;Winter_01.gif&quot;</span><span class="p">);</span>
+    <span class="n">loadImage</span><span class="p">(</span><span class="n">img</span><span class="p">);</span>
+    <span class="n">img</span><span class="o">.</span><span class="n">setLocation</span><span class="p">(</span><span class="n">loc</span><span class="p">);</span>
+
+    <span class="sr">//</span> <span class="o">***</span> <span class="n">PERSIST</span> <span class="o">***</span>
+    <span class="n">try</span> <span class="p">{</span>
+        <span class="n">em</span><span class="o">.</span><span class="n">getTransaction</span><span class="p">()</span><span class="o">.</span><span class="n">begin</span><span class="p">();</span>
+        <span class="sr">//</span> <span class="n">Persist</span> <span class="n">the</span> <span class="n">entity</span> <span class="n">with</span> <span class="n">non</span><span class="o">-</span><span class="n">matching</span> <span class="n">extension</span> <span class="ow">and</span> <span class="n">type</span>
+        <span class="n">em</span><span class="o">.</span><span class="n">persist</span><span class="p">(</span><span class="n">img</span><span class="p">);</span>
+    <span class="p">}</span> <span class="n">catch</span> <span class="p">(</span><span class="n">ConstraintViolationException</span> <span class="n">cve</span><span class="p">)</span> <span class="p">{</span>
+        <span class="sr">//</span> <span class="n">Transaction</span> <span class="n">was</span> <span class="n">marked</span> <span class="k">for</span> <span class="n">rollback</span><span class="p">,</span> <span class="n">roll</span> <span class="n">it</span> <span class="n">back</span> <span class="ow">and</span>
+        <span class="sr">//</span> <span class="n">start</span> <span class="n">a</span> <span class="k">new</span> <span class="n">one</span>
+        <span class="n">em</span><span class="o">.</span><span class="n">getTransaction</span><span class="p">()</span><span class="o">.</span><span class="n">rollback</span><span class="p">();</span>
+        <span class="n">em</span><span class="o">.</span><span class="n">getTransaction</span><span class="p">()</span><span class="o">.</span><span class="n">begin</span><span class="p">();</span>
+        <span class="sr">//</span> <span class="n">Fix</span> <span class="n">the</span> <span class="n">file</span> <span class="n">type</span> <span class="ow">and</span> <span class="n">re</span><span class="o">-</span><span class="n">try</span> <span class="n">the</span> <span class="n">persist</span><span class="o">.</span>
+        <span class="n">img</span><span class="o">.</span><span class="n">setType</span><span class="p">(</span><span class="n">ImageType</span><span class="o">.</span><span class="n">GIF</span><span class="p">);</span>
+        <span class="n">em</span><span class="o">.</span><span class="n">persist</span><span class="p">(</span><span class="n">img</span><span class="p">);</span>
+        <span class="n">em</span><span class="o">.</span><span class="n">getTransaction</span><span class="p">()</span><span class="o">.</span><span class="n">commit</span><span class="p">();</span>
+    <span class="p">}</span>
+
+    <span class="sr">//</span> <span class="o">***</span> <span class="n">UPDATE</span> <span class="o">***</span>
+    <span class="n">try</span> <span class="p">{</span>
+        <span class="n">em</span><span class="o">.</span><span class="n">getTransaction</span><span class="p">()</span><span class="o">.</span><span class="n">begin</span><span class="p">();</span>
+        <span class="sr">//</span> <span class="n">Modify</span> <span class="n">the</span> <span class="n">file</span> <span class="n">name</span> <span class="n">to</span> <span class="n">a</span> <span class="n">non</span><span class="o">-</span><span class="n">matching</span> <span class="n">file</span> <span class="n">name</span> 
+        <span class="sr">//</span> <span class="ow">and</span> <span class="n">commit</span> <span class="n">to</span> <span class="n">trigger</span> <span class="n">an</span> <span class="n">update</span>
+        <span class="n">img</span><span class="o">.</span><span class="n">setFileName</span><span class="p">(</span><span class="s">&quot;Winter_01.jpg&quot;</span><span class="p">);</span>
+        <span class="n">em</span><span class="o">.</span><span class="n">getTransaction</span><span class="p">()</span><span class="o">.</span><span class="n">commit</span><span class="p">();</span>
+    <span class="p">}</span>  <span class="n">catch</span> <span class="p">(</span><span class="n">ConstraintViolationException</span> <span class="n">cve</span><span class="p">)</span> <span class="p">{</span>
+        <span class="sr">//</span> <span class="n">Handle</span> <span class="n">the</span> <span class="n">exception</span><span class="o">.</span>  <span class="n">The</span> <span class="n">commit</span> <span class="n">failed</span> <span class="n">so</span> <span class="n">the</span> <span class="n">transaction</span>
+        <span class="sr">//</span> <span class="n">was</span> <span class="n">already</span> <span class="n">rolled</span> <span class="n">back</span><span class="o">.</span>
+        <span class="n">handleConstraintViolation</span><span class="p">(</span><span class="n">cve</span><span class="p">);</span>
+    <span class="p">}</span>
+    <span class="sr">//</span> <span class="n">The</span> <span class="n">update</span> <span class="n">failure</span> <span class="n">caused</span> <span class="n">img</span> <span class="n">to</span> <span class="n">be</span> <span class="n">detached</span><span class="o">.</span> <span class="n">It</span> <span class="n">must</span> <span class="n">be</span> <span class="n">merged</span> <span class="n">back</span> 
+    <span class="sr">//</span> <span class="n">into</span> <span class="n">the</span> <span class="n">persistence</span> <span class="n">context</span><span class="o">.</span>
+    <span class="n">img</span> <span class="o">=</span> <span class="n">em</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="n">img</span><span class="p">);</span>
+
+    <span class="sr">//</span> <span class="o">***</span> <span class="n">REMOVE</span> <span class="o">***</span>
+    <span class="n">em</span><span class="o">.</span><span class="n">getTransaction</span><span class="p">()</span><span class="o">.</span><span class="n">begin</span><span class="p">();</span>
+    <span class="n">try</span> <span class="p">{</span>
+        <span class="sr">//</span> <span class="n">Remove</span> <span class="n">the</span> <span class="n">type</span> <span class="ow">and</span> <span class="n">commit</span> <span class="n">to</span> <span class="n">trigger</span> <span class="n">removal</span>

[... 237 lines stripped ...]


Mime
View raw message