<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-1306958590608174053</atom:id><lastBuildDate>Sun, 13 May 2012 20:10:31 +0000</lastBuildDate><category>Redmine</category><category>Connection Pool</category><category>AOP</category><category>Archetype Plugin</category><category>Mockito</category><category>Hibernate Validator</category><category>generic methods</category><category>Apache Commons IO</category><category>Metro</category><category>Seam</category><category>JPA 2</category><category>Type inference</category><category>Dependency Injection</category><category>scripting languages</category><category>Warbler</category><category>JDT</category><category>IntelliJ IDEA</category><category>Tutorial</category><category>JSF 2</category><category>Oracle</category><category>DTO</category><category>JSR 349</category><category>aspect-oriented programming</category><category>MessageDigest</category><category>CRC32</category><category>Bean Validation</category><category>EJB</category><category>design pattern</category><category>Google Guice</category><category>JSR 299</category><category>downloads</category><category>Jetty</category><category>JRuby</category><category>JSR 223</category><category>JSR 317</category><category>shell</category><category>Apache Ant</category><category>JAXB</category><category>Java Magazin</category><category>SpEL</category><category>Data Source</category><category>JAX-WS</category><category>CDI</category><category>MD5</category><category>Spring</category><category>JUnit</category><category>Ruby on Rails</category><category>DBUnit</category><category>Woodstox</category><category>Archetype Catalog</category><category>Joda Time API</category><category>OSGi</category><category>MySQL</category><category>Google Code</category><category>OpenEJB</category><category>XML</category><category>Generics</category><category>wstx-asl</category><category>Java</category><category>web services</category><category>JSR 303</category><category>key words: JBoss Community Award</category><category>annotation</category><category>RCP</category><category>XPath</category><category>JMX</category><category>interceptor</category><category>Maven</category><category>Proxy</category><category>languages</category><category>Eclipse</category><category>dependency</category><category>contract-first</category><category>statistics</category><category>Glassfish</category><category>SVN</category><category>XmlBeans</category><category>Blog</category><category>visitor pattern</category><category>checksum</category><title>Musings of a Programming Addict</title><description /><link>http://musingsofaprogrammingaddict.blogspot.com/</link><managingEditor>noreply@blogger.com (Gunnar Morling)</managingEditor><generator>Blogger</generator><openSearch:totalResults>52</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/MusingsOfAProgrammingAddict" /><feedburner:info uri="musingsofaprogrammingaddict" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-7056300782973436828</guid><pubDate>Sun, 09 Oct 2011 17:36:00 +0000</pubDate><atom:updated>2011-10-09T19:36:35.240+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">OSGi</category><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">Eclipse</category><title>Using Pax Runner with Eclipse 3.6</title><description>&lt;p&gt;While working on a little pet project based on OSGi I wanted to use the &lt;a href="http://team.ops4j.org/wiki/display/paxrunner/Pax+Runner"&gt;Pax Runner&lt;/a&gt; Eclipse plug-in to launch my OSGi application on the &lt;a href="http://felix.apache.org/"&gt;Apache Felix&lt;/a&gt; OSGi framework.&lt;/p&gt;&lt;p&gt;Unfortunately this attempt resulted in the following error:&lt;/p&gt;&lt;p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;java.lang.NoClassDefFoundError: org/eclipse/pde/internal/ui/launcher/LaunchArgumentsHelper&lt;tt&gt;
&lt;/tt&gt;at org.ops4j.pax.cursor.Utils.getVMArgsOptions(Utils.java:216)&lt;tt&gt;
&lt;/tt&gt;at org.ops4j.pax.cursor.LaunchConfiguration.getProgramArguments(LaunchConfiguration.java:156)&lt;tt&gt;
&lt;/tt&gt;at org.eclipse.pde.launching.AbstractPDELaunchConfiguration.launch(AbstractPDELaunchConfiguration.java:72)&lt;tt&gt;
&lt;/tt&gt;at org.eclipse.pde.launching.OSGiLaunchConfigurationDelegate.launch(OSGiLaunchConfigurationDelegate.java:47)&lt;tt&gt;
&lt;/tt&gt;at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:853)&lt;tt&gt;
&lt;/tt&gt;at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:702)&lt;tt&gt;
&lt;/tt&gt;at org.eclipse.debug.internal.ui.DebugUIPlugin.buildAndLaunch(DebugUIPlugin.java:923)&lt;tt&gt;
&lt;/tt&gt;at org.eclipse.debug.internal.ui.DebugUIPlugin$8.run(DebugUIPlugin.java:1126)&lt;tt&gt;
&lt;/tt&gt;at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/p&gt;&lt;p&gt;This looked pretty much like an incompatability between the Pax Runner plug-in and the Eclipse platform. And indeed the plug-in unfortunately doesn't seem to keep up with PDE-internal changes in recent Eclipse versions due to &lt;a href="http://permalink.gmane.org/gmane.comp.java.ops4j.general/12273"&gt;limited developer resources&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;Further googling then led me to &lt;a href="http://team.ops4j.org/browse/PAXRUNNER-353"&gt;PAXRUNNER-353&lt;/a&gt; at Pax Runner's issue tracker.&lt;/p&gt;&lt;p&gt;The ticket itself is not yet resolved, but the good news is that &lt;a href="http://tux2323.blogspot.com/"&gt;Christian Baranowski&lt;/a&gt; (whom I had the pleasure to meet during the &lt;a href="http://germany.osgiusers.org/Main/SummerOCC2011"&gt;OSGi code camp&lt;/a&gt; last week) created a &lt;a href="https://github.com/tux2323/org.ops4j.pax.runner/tree/master/pax-runner-eclipse"&gt;fork&lt;/a&gt; on GitHub fixing the issue for now. So let's hope that this fix gets quickly merged into the main branch.&lt;/p&gt;&lt;p&gt;Until then Christian even has established a temporary Eclipse &lt;a href="http://tux2323.github.com/pax-runner-update-site/"&gt;update site&lt;/a&gt; which makes upgrading the plug-in to the forked version a breeze. &lt;/p&gt;&lt;p&gt;So my kudos go to Christian (for fixing the plug-in) and to GitHub (for making forking easy) :-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-7056300782973436828?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/YopnxCt1GFs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/YopnxCt1GFs/using-pax-runner-with-eclipse-36.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>0</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2011/10/using-pax-runner-with-eclipse-36.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-4980452487227178702</guid><pubDate>Mon, 01 Aug 2011 20:36:00 +0000</pubDate><atom:updated>2011-08-01T22:36:48.008+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">JSR 349</category><category domain="http://www.blogger.com/atom/ns#">Bean Validation</category><title>What would YOU like to see included in Bean Validation 1.1?</title><description>&lt;p&gt;Maybe you know it already: last week &lt;a href="http://jcp.org/en/jsr/detail?id=303"&gt;JSR 349&lt;/a&gt; successfully passed the review ballot, meaning that the work on a new release of the Bean Validation API has officially started.&lt;/p&gt;&lt;p&gt;I'm really excited about this, because I've got the pleasure to be part of the JSR 349 expert group. I haven't been member of such a comitee before, so I guess this will be exciting times and I'll surely learn a whole lot of new things during the work on the specification.&lt;/p&gt;&lt;p&gt;What's most important right now is your feedback: what new features would you like to see included in Bean Validation 1.1, what problems did you face when working with BV 1.0 which you think should be addressed in the next release?&lt;/p&gt;&lt;p&gt;Your input and feedback is highly welcome at several places:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The Bean Validation &lt;a href="https://forum.hibernate.org/viewforum.php?f=26"&gt;feedback forum&lt;/a&gt; is a good platform for discussing ideas, requests for clarifications etc.&lt;/li&gt;
&lt;li&gt;For concrete feature requests or bug reports you can open an issue at the Bean Validation &lt;a href="http://beanvalidation.org/issues"&gt;issue tracker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;As a starting point you might want to check out &lt;a href="http://in.relation.to/Bloggers/BeanValidation11HasStartedJoinUs"&gt;these two&lt;/a&gt; &lt;a href="http://in.relation.to/Bloggers/JSRBeanValidation11WhatToPutIn"&gt;blog posts&lt;/a&gt; by Emmanuel Bernard (the Bean Validation spec. lead), where a lot of possible features are discussed.&lt;/p&gt;&lt;p&gt;Finally I'd like to point your attention to &lt;a href="http://beanvalidation.org/"&gt;http://beanvalidation.org/&lt;/a&gt;, the JSR's official web site. There you'll find everything related, e.g. a &lt;a href="http://beanvalidation.org/news/"&gt;news section&lt;/a&gt;, the &lt;a href="http://beanvalidation.org/roadmap/"&gt;road map&lt;/a&gt; and also the Bean Validation 1.0 &lt;a href="http://beanvalidation.org/1.0/spec"&gt;spec. document&lt;/a&gt; for reference.&lt;/p&gt;&lt;p&gt;Now it's up to you &amp;#150; tell us what would YOU like to see included in Bean Validation 1.1.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-4980452487227178702?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/s0TPdFfg8I8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/s0TPdFfg8I8/what-would-you-like-to-see-included-in.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>0</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2011/08/what-would-you-like-to-see-included-in.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-5377865459692769011</guid><pubDate>Sun, 08 May 2011 11:10:00 +0000</pubDate><atom:updated>2011-05-08T13:10:26.775+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">Hibernate Validator</category><category domain="http://www.blogger.com/atom/ns#">Bean Validation</category><category domain="http://www.blogger.com/atom/ns#">Seam</category><title>Introducing Seam Validation</title><description>&lt;p&gt;&lt;em&gt;Note: This article originally appeared on &lt;a href="http://in.relation.to/Bloggers/SeamModuleSpotlightSeamValidation"&gt;in.relation.to&lt;/a&gt; as part of the Seam Module Spotlight series. In order to spread the word on Seam Validation I thought it might be a good idea to post it in this blog, too.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://seamframework.org/Seam3/ValidationModule"&gt;Seam Validation&lt;/a&gt; is a relatively new Seam module which provides an integration between &lt;a href="http://www.hibernate.org/subprojects/validator.html"&gt;Hibernate Validator&lt;/a&gt; which is the reference implementation of the Bean Validation standard (&lt;a href="http://jcp.org/en/jsr/detail?id=303"&gt;JSR 303&lt;/a&gt;) and CDI. The module's functionality falls into two areas:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Enhanced dependency injection services for validators, validator factories and constraint validators&lt;/li&gt;
&lt;li&gt;Automatic validation of method parameters and return values based on Hibernate Validator's method validation API&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Let's take a closer look at these features in the following.&lt;/p&gt;&lt;h2&gt;Dependency injection services&lt;/h2&gt;&lt;p&gt;The Bean Validation API is an integral part of the Java EE platform. So when running on a Java EE 6 compatible application server such as &lt;a href="http://www.jboss.org/jbossas/"&gt;JBoss AS 6&lt;/a&gt; you can easily retrieve &lt;code&gt;Validator&lt;/code&gt; and &lt;code&gt;ValidatorFactory&lt;/code&gt; instances via dependency injection.&lt;/p&gt;&lt;p&gt;Unfortunately this is not working out of the box when running in non-EE environments such as plain servlet containers. But don't worry, Seam Validation comes to the rescue. By adding the module as dependency to your project, validators and validator factories can be obtained using &lt;code&gt;@Inject&lt;/code&gt;:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Foo&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Inject&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="pt"&gt;Validator&lt;/span&gt; validator;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; doSomething() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        Bar bar = &lt;span class="kw"&gt;new&lt;/span&gt; Bar();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="pt"&gt;Set&lt;/span&gt;&amp;lt;ConstraintViolation&amp;lt;Bar&amp;gt;&amp;gt; constraintViolations = validator.validate(bar);&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="c"&gt;//examine the violations ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;But Seam Validation goes one step further and enables dependency injection also within constraint validator implementations. For instance we might have a custom constraint &lt;code&gt;@ValidLicensePlate&lt;/code&gt; which is used to ensure that a car has a license plate which is properly registered, still valid etc.:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Car&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@ValidLicensePlate&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="pt"&gt;String&lt;/span&gt; licensePlate;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;//constructor, getter, setter etc.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;In order to perform the required checks the constraint's validator invokes some sort of registration service (note: accessing external services can potentially be an expensive operation, so it may be a good idea to put the constraint into a separate &lt;a href="http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html/validator-usingvalidator.html#validator-usingvalidator-validationgroups"&gt;validation group&lt;/a&gt;, but that's out of scope for this article). The Seam Validation module allows to inject this service into the validator as into any other CDI bean:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;ValidLicensePlateValidator&lt;/span&gt; &lt;span class="di"&gt;implements&lt;/span&gt; ConstraintValidator&amp;lt;ValidLicensePlate, &lt;span class="pt"&gt;String&lt;/span&gt;&amp;gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Inject&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; RegistrationService registrationService;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; initialize(ValidLicensePlate constraintAnnotation) {&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;boolean&lt;/span&gt; isValid(&lt;span class="pt"&gt;String&lt;/span&gt; value, ConstraintValidatorContext context) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (value == &lt;span class="pc"&gt;null&lt;/span&gt;) {&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="pc"&gt;true&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="c"&gt;//delegate to registration service&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; registrationService.isValid(value);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;There is just on more step required before the &lt;code&gt;@ValidLicensePlate&lt;/code&gt; constraint can be used: We have to register Seam Validation's constraint validator factory with the Bean Validation provider. This happens by putting a file named validation.xml with the following content into the META-INF folder of the application:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="pp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;validation-config&lt;/span&gt; &lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xmlns&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://jboss.org/xml/ns/javax/validation/configuration&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xmlns:xsi&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xsi:schemaLocation&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.0.xsd&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;constraint-validator-factory&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        org.jboss.seam.validation.InjectingConstraintValidatorFactory&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;/constraint-validator-factory&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/validation-config&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;h2&gt;Method validation&lt;/h2&gt;&lt;p&gt;The other main feature of Seam Validation besides dependency injection is the automatic validation of method parameters and return values based on the &lt;a href="http://docs.jboss.org/hibernate/validator/4.2/api/index.html?org/hibernate/validator/method/MethodValidator.html"&gt;API for method validation&lt;/a&gt; introduced with Hibernate Validator 4.2 (note: at the time of writing Hibernate Validator 4.2 is released as Beta version, but no major changes are expected until the final release).&lt;/p&gt;&lt;p&gt;This API provides an easy-to-use facility for the "Programming by Contract" approach to program design based on the concepts defined by the Bean Validation API. That means that any Bean Validation constraint can be used to describe&lt;/p&gt;&lt;ul&gt;&lt;li&gt;the preconditions that must be met before a method may be invoked (by annotating method parameters with constraints) and&lt;/li&gt;
&lt;li&gt;the postconditions that are guaranteed after a method invocation returns (by annotating methods).&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Things should become clearer with an example:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@AutoValidating&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;RentalStation&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Valid&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; Car rentCar(&lt;span class="at"&gt;@NotNull&lt;/span&gt; CustomerPK customerPK, &lt;span class="at"&gt;@NotNull&lt;/span&gt; &lt;span class="at"&gt;@Future&lt;/span&gt; &lt;span class="pt"&gt;Date&lt;/span&gt; startDate, &lt;span class="at"&gt;@Min&lt;/span&gt;(&lt;span class="i"&gt;1&lt;/span&gt;) &lt;span class="ty"&gt;int&lt;/span&gt; durationInDays) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="c"&gt;//highly complex car rental business logic ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Here the following pre- and postconditions are applied onto the &lt;code&gt;rentCar()&lt;/code&gt; method:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The customer's primary key may not be null&lt;/li&gt;
&lt;li&gt;The rental start date must not be null and must be in the future&lt;/li&gt;
&lt;li&gt;The rental duration must be at least one day&lt;/li&gt;
&lt;li&gt;The returned object must be valid with respect to all constraints of the &lt;code&gt;Car&lt;/code&gt; class&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;By annotating the class &lt;code&gt;RentalStation&lt;/code&gt; with &lt;code&gt;@AutoValidating&lt;/code&gt;, all these constraints are automatically validated by a method interceptor whenever the &lt;code&gt;rentCar()&lt;/code&gt; method is invoked. If any of the constraints can't be validated successfully, a &lt;a href="http://docs.jboss.org/hibernate/validator/4.2/api/index.html?org/hibernate/validator/method/MethodConstraintViolation.html"&gt;runtime exception&lt;/a&gt; describing the occurred constraint violation(s) is thrown.&lt;/p&gt;&lt;p&gt;This approach has several advantages over traditional parameter and return value checking:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The checks don't have to be performed by hand. This results in less boiler-plate code to write (and to read).&lt;/li&gt;
&lt;li&gt;A method's pre- and postconditions are part of its API and generated documentation. It's not necessary to add comments such as "returns never null", as this information will automatically be put into the generated JavaDoc. This results in less redundancies and hence in less potential inconsistencies between implementation and documentation.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Future steps&lt;/h2&gt;&lt;p&gt;This concludes our short tour through the Seam Validation module. If you feel like trying out the module yourself, the &lt;a href="http://seamframework.org/Seam3/ValidationModule"&gt;module home page&lt;/a&gt; is the right starting point. You might also be interested in the module's &lt;a href="http://docs.jboss.org/seam/3/validation/snapshot/reference/en-US/html_single/"&gt;reference guide&lt;/a&gt;, and in case you found a bug or want to create a feature request the module's &lt;a href="https://issues.jboss.org/browse/SEAMVALIDATE"&gt;JIRA instance&lt;/a&gt; is the place to go.&lt;/p&gt;&lt;p&gt;Possible future developments of Seam Validation include a closer integration with other Seam 3 modules, the possibility to chose the validation groups to be used for method validation and the evaluation of standard bean constraints upon method validation.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-5377865459692769011?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/xRtL4XnCGGo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/xRtL4XnCGGo/introducing-seam-validation.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>0</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2011/05/introducing-seam-validation.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-571227904595988835</guid><pubDate>Sat, 05 Mar 2011 16:39:00 +0000</pubDate><atom:updated>2011-03-05T17:39:52.697+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">key words: JBoss Community Award</category><title>2011 JBoss Community Awards: I need your vote!</title><description>&lt;p&gt;I need your help. &lt;/p&gt;&lt;p&gt;To be more concise, I need your vote for the &lt;a href="http://www.jboss.org/jbcra/"&gt;2011 JBoss Community Recognition Awards&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;These awards are an effort of &lt;a href="http://www.jboss.org/"&gt;JBoss/Red Hat&lt;/a&gt; to honor significant contributions to the JBoss community over the last year and I'm more than proud to say that I've been nominated in the "New Features" category for my contributions to &lt;a href="http://validator.hibernate.org/"&gt;Hibernate Validator&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;So if you appreciate my work on Hibernate Validator &amp;#150; e.g. the HV &lt;a href="http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#d0e2704"&gt;annotation processor&lt;/a&gt; or the &lt;a href="http://musingsofaprogrammingaddict.blogspot.com/2011/01/method-validation-with-hibernate.html"&gt;method validation feature&lt;/a&gt; I've built for HV 4.2 &amp;#150; or the &lt;a href="http://seamframework.org/Seam3/ValidationModule"&gt;Validation module&lt;/a&gt; for Seam 3 (I'll blog on this in a separate post) I've recently started, just head over to &lt;a href="http://community.jboss.org/polls/1066"&gt;the poll&lt;/a&gt; and give me your vote. The voting is open until April, 2nd.&lt;/p&gt;&lt;p&gt;And if you really like my work, go and tell your friends that they should vote for me, too.&lt;/p&gt;&lt;p&gt;Just in case you feel like you need some more information to make a profound vote you might also check out my &lt;a href="http://www.jboss.org/jbcra/nominees.html"&gt;nominee description&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Another nomination I'd like to mention is the one of my fellow developer Kevin Pollet in the "Bug Fixes" category. He has done some really awesome work for HV 4.2. Besides fixing many bugs he implemented several new features like the integration with the Joda time API or the support for dynamic default group sequence definitions.&lt;/p&gt;&lt;p&gt;So when you (and your friends) have voted for me, don't forget to &lt;a href="http://community.jboss.org/polls/1067"&gt;vote&lt;/a&gt; for Kevin, too :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-571227904595988835?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/o6ATeukA9oo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/o6ATeukA9oo/2011-jboss-community-awards-i-need-your.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>0</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2011/03/2011-jboss-community-awards-i-need-your.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-2511920072509990487</guid><pubDate>Sun, 16 Jan 2011 21:32:00 +0000</pubDate><atom:updated>2011-01-16T22:32:13.593+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">JSR 303</category><category domain="http://www.blogger.com/atom/ns#">Hibernate Validator</category><category domain="http://www.blogger.com/atom/ns#">Bean Validation</category><title>Method Validation with Hibernate Validator 4.2</title><description>&lt;p&gt;Earlier this week the first beta version of Hibernate Validator 4.2 was released. Hardy's announcement on &lt;a href="http://in.relation.to/18074.lace"&gt;in.relation.to&lt;/a&gt; describes in detail what's new in this release, so be sure to check it out.&lt;/p&gt;&lt;p&gt;One of the new features I'm really excited about is method validation, which I therefore would like to discuss in more detail in the following.&lt;/p&gt;&lt;h2&gt;What's it about?&lt;/h2&gt;&lt;p&gt;Up to now constraint annotations were only supported at fields or at getter methods for property constraints and at type declarations for class-level constraints.&lt;/p&gt;&lt;p&gt;With HV 4.2 it is now also possible to use constraint annotations for a programming style known as &lt;a href="http://en.wikipedia.org/wiki/Programming_by_contract"&gt;"Programming by Contract"&lt;/a&gt;. More specifically this means that any Bean Validation constraints (built-in as well as custom constraints) can be used to specify &lt;/p&gt;&lt;ul&gt;&lt;li&gt;any preconditions that must be met before a method invocation (by annotating method parameters with constraints) and&lt;/li&gt;
&lt;li&gt;any postconditions that are guaranteed after a method invocation (by annotating methods)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;As example let's consider the following class from a fictitious video rental application:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;MovieRepository&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="at"&gt;@NotNull&lt;/span&gt; &lt;span class="pt"&gt;Set&lt;/span&gt;&amp;lt;Movie&amp;gt; findMoviesByTitle( &lt;tt&gt;
&lt;/tt&gt;        &lt;span class="at"&gt;@NotNull&lt;/span&gt; &lt;span class="at"&gt;@Size&lt;/span&gt;(min = &lt;span class="i"&gt;3&lt;/span&gt;) &lt;span class="pt"&gt;String&lt;/span&gt; title) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="c"&gt;//search movie in database ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    }   &lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;The following pre- and postconditions will hold here (provided the method validation is triggered automatically by some integration layer, see below):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The title parameter is guaranteed to be not null and at least 3 characters long&lt;/li&gt;
&lt;li&gt;The return set of movies is guaranteed to be not null&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Compared to traditional ways of parameter or result value checking this approach has two big advantages:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;These checks don't have to be performed manually, which results in less code to write and maintain. You'll never again have to throw IllegalArgumentExceptions or similar by hand.&lt;/li&gt;
&lt;li&gt;The pre- and postconditions of a method don't have to be expressed again in the method's JavaDoc, since any of it's annotations will automatically be included in the generated JavaDoc. This means less redundancy which reduces the chance of inconsistencies between implementation and comments.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Method validation is not restricted to constraints related to parameters or to return values themselves. Using the @Valid annotation it is also possible to recursively validate parameters or return values:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;UserRepository&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; persistUser(&lt;span class="at"&gt;@NotNull&lt;/span&gt; &lt;span class="at"&gt;@Valid&lt;/span&gt; User user) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="c"&gt;//persist user in database ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    }   &lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;In this example not only the @NotNull constraint at the user parameter would be checked, but also any constraints defined at the User type. As known from standard Bean Validation the @Valid annotation could also be applied to array-, &lt;a href="http://download.oracle.com/javase/6/docs/api/java/lang/Iterable.html"&gt;Iterable&lt;/a&gt;- and &lt;a href="http://download.oracle.com/javase/6/docs/api/java/util/Map.html"&gt;Map&lt;/a&gt;-typed parameters or return values.&lt;/p&gt;&lt;h2&gt;The MethodValidator interface&lt;/h2&gt;&lt;p&gt;For the purposes of method validation Hibernate Validator defines the new interface &lt;a href="http://docs.jboss.org/hibernate/validator/4.2/api/org/hibernate/validator/MethodValidator.html"&gt;MethodValidator&lt;/a&gt; (any type or method names are working titles and might &lt;a href="http://opensource.atlassian.com/projects/hibernate/browse/HV-415"&gt;change&lt;/a&gt; until HV 4.2 is final), which provides methods for parameter and return value validation:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;interface&lt;/span&gt; &lt;span class="cl"&gt;MethodValidator&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &amp;lt;T&amp;gt; &lt;span class="pt"&gt;Set&lt;/span&gt;&amp;lt;MethodConstraintViolation&amp;lt;T&amp;gt;&amp;gt; validateParameter(&lt;tt&gt;
&lt;/tt&gt;        T object, &lt;span class="pt"&gt;Method&lt;/span&gt; method, &lt;span class="pt"&gt;Object&lt;/span&gt; parameterValue, &lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ty"&gt;int&lt;/span&gt; parameterIndex, &lt;span class="pt"&gt;Class&lt;/span&gt;&amp;lt;?&amp;gt;... groups);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &amp;lt;T&amp;gt; &lt;span class="pt"&gt;Set&lt;/span&gt;&amp;lt;MethodConstraintViolation&amp;lt;T&amp;gt;&amp;gt; validateParameters(&lt;tt&gt;
&lt;/tt&gt;        T object, &lt;span class="pt"&gt;Method&lt;/span&gt; method, &lt;span class="pt"&gt;Object&lt;/span&gt;&lt;span class="ty"&gt;[]&lt;/span&gt; parameterValues, &lt;span class="pt"&gt;Class&lt;/span&gt;&amp;lt;?&amp;gt;... groups);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &amp;lt;T&amp;gt; &lt;span class="pt"&gt;Set&lt;/span&gt;&amp;lt;MethodConstraintViolation&amp;lt;T&amp;gt;&amp;gt; validateReturnValue(&lt;tt&gt;
&lt;/tt&gt;        T object, &lt;span class="pt"&gt;Method&lt;/span&gt; method, &lt;span class="pt"&gt;Object&lt;/span&gt; returnValue, &lt;span class="pt"&gt;Class&lt;/span&gt;&amp;lt;?&amp;gt;... groups);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;To get hold of a method validator, &lt;a href="http://download.oracle.com/javaee/6/api/javax/validation/Validator.html#unwrap(java.lang.Class)"&gt;unwrap&lt;/a&gt; an instance of HV's &lt;a href="http://download.oracle.com/javaee/6/api/javax/validation/Validator.html"&gt;Validator&lt;/a&gt; implementation as follows:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;MethodValidator validator = Validation.byProvider( HibernateValidator.class )&lt;tt&gt;
&lt;/tt&gt;    .configure()&lt;tt&gt;
&lt;/tt&gt;    .buildValidatorFactory()&lt;tt&gt;
&lt;/tt&gt;    .getValidator()&lt;tt&gt;
&lt;/tt&gt;    .unwrap( MethodValidator.class );&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;All of MethodValidator's methods return a set of &lt;a href="http://docs.jboss.org/hibernate/validator/4.2/api/org/hibernate/validator/MethodConstraintViolation.html"&gt;MethodConstraintValidation&lt;/a&gt;s which describe in detail any constraint violations that occurred during validation. &lt;code&gt;MethodConstraintValidation&lt;/code&gt; extends the standard &lt;a href="http://download.oracle.com/javaee/6/api/javax/validation/ConstraintViolation.html"&gt;ConstraintViolation&lt;/a&gt; and provides additional information such as method and parameter causing a constraint violation:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;interface&lt;/span&gt; &lt;span class="cl"&gt;MethodConstraintViolation&lt;/span&gt;&amp;lt;T&amp;gt; &lt;span class="di"&gt;extends&lt;/span&gt; ConstraintViolation&amp;lt;T&amp;gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;enum&lt;/span&gt; Kind {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        PARAMETER,&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        RETURN_VALUE&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pt"&gt;Method&lt;/span&gt; getMethod();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pt"&gt;Integer&lt;/span&gt; getParameterIndex();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pt"&gt;String&lt;/span&gt; getParameterName();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    Kind getKind();&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Unfortunately the byte code of a Java program normally doesn't contain any information on parameter names, therefore &lt;code&gt;getParameterName()&lt;/code&gt; for now returns synthetic names such as &lt;code&gt;arg0&lt;/code&gt; etc. For a future release we are investigating approaches for parameter naming, e.g. by leveraging JSR 330's @Named annotation. I created a JIRA &lt;a href="http://opensource.atlassian.com/projects/hibernate/browse/HV-409"&gt;issue&lt;/a&gt; for this, so if you have any feedback on this just add a comment to the ticket.&lt;/p&gt;&lt;h2&gt;Triggering method validation&lt;/h2&gt;&lt;p&gt;Hibernate Validator itself only provides the engine for method validation but it does not deal with triggering such a validation.&lt;/p&gt;&lt;p&gt;Instead this is typically done using frameworks/APIs which provide AOP or method interception services such as &lt;a href="http://www.eclipse.org/aspectj/"&gt;AspectJ&lt;/a&gt; or &lt;a href="http://jcp.org/en/jsr/detail?id=299"&gt;CDI&lt;/a&gt;. But also plain Java dynamic proxies can basically do the trick.&lt;/p&gt;&lt;p&gt;Typically such a validation interceptor does the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;intercept each method call to be validated,&lt;/li&gt;
&lt;li&gt;validate the invocation's parameter values,&lt;/li&gt;
&lt;li&gt;proceed with the method invocation and&lt;/li&gt;
&lt;li&gt;finally validate the invocation's return value. &lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;If any of the two validation steps yields one ore more constraint violations the interceptor typically throws a &lt;a href="http://docs.jboss.org/hibernate/validator/4.2/api/org/hibernate/validator/MethodConstraintViolationException.html"&gt;MethodConstraintViolationException&lt;/a&gt; containing the constraint violations that have occurred.&lt;/p&gt;&lt;h2&gt;Trying it out yourself&lt;/h2&gt;&lt;p&gt;To see whether method validation works out as intended I started a project at GitHub called &lt;a href="https://github.com/gunnarmorling/methodvalidation-integration"&gt;methodvalidation-integration&lt;/a&gt; which provides validation handlers for some interception technologies popular these days. &lt;/p&gt;&lt;p&gt;Currently there are implementations for CDI as well as &lt;a href="http://code.google.com/p/google-guice/"&gt;Google Guice&lt;/a&gt; and an &lt;a href="http://download.oracle.com/javase/6/docs/api/java/lang/reflect/InvocationHandler.html"&gt;InvocationHandler&lt;/a&gt; which can be used with JDK dynamic proxies. I also plan to add support for Spring AOP/AspectJ when time permits.&lt;/p&gt;&lt;p&gt;To try method validation out yourself just get the bits from GitHub and have a look at the test in each of the sub-projects. Just give it a try and let me know how everything works.&lt;/p&gt;&lt;h2&gt;Future steps&lt;/h2&gt;&lt;p&gt;This post introduced the new method validation feature which will be part of Hibernate Validator 4.2. The first beta release contains the basic implementations of this, so we are more than interested in you feedback on this. Please report any bugs in HV's &lt;a href="http://opensource.atlassian.com/projects/hibernate/browse/HV"&gt;JIRA instance&lt;/a&gt;, any questions or ideas for improvement are also highly welcome in HV's &lt;a href="https://forum.hibernate.org/viewforum.php?f=9"&gt;forum&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;For HV 4.2 Beta2 we plan to &lt;a href="http://opensource.atlassian.com/projects/hibernate/browse/HV-372"&gt;add documentation&lt;/a&gt; on the method validation feature to HV's &lt;a href="http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html/"&gt;reference guide&lt;/a&gt; which will also describe some advanced topics such as using method validation with group sequences etc. We will also &lt;a href="http://opensource.atlassian.com/projects/hibernate/browse/HV-371"&gt;add support&lt;/a&gt; for method level constraints to the constraint &lt;a href="http://docs.jboss.org/hibernate/validator/4.2/reference/en-US/html/validator-metadata-api.html"&gt;meta-data API&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;Two further ideas scheduled for after 4.2 are providing the ability to specify method level constraints using &lt;a href="http://opensource.atlassian.com/projects/hibernate/browse/HV-373"&gt;XML&lt;/a&gt; and using the programmatic constraint configuration API.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-2511920072509990487?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/-jp13WxBnsw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/-jp13WxBnsw/method-validation-with-hibernate.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>17</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2011/01/method-validation-with-hibernate.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-2487404757547043075</guid><pubDate>Mon, 27 Dec 2010 17:38:00 +0000</pubDate><atom:updated>2010-12-27T18:38:59.245+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">IntelliJ IDEA</category><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">Maven</category><title>Setting the active Maven profile in IntelliJ IDEA</title><description>&lt;p&gt;This is more a note to myself, but in case someone else wonders how to specify the active Maven profile in &lt;a href="http://www.jetbrains.com/idea/"&gt;IntelliJ IDEA&lt;/a&gt; for projects containing several profiles, that's the way to go:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Open the "Maven Projects" window by selecting "Window" - "Tool Windows" - "Maven Projects"&lt;/li&gt;
&lt;li&gt;Expand the "Profiles" node and select the profile you want to use&lt;/li&gt;

&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-2487404757547043075?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/BmLP1yEwqbI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/BmLP1yEwqbI/setting-active-maven-profile-in.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>0</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/12/setting-active-maven-profile-in.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-9094520327516244949</guid><pubDate>Mon, 27 Dec 2010 13:58:00 +0000</pubDate><atom:updated>2010-12-27T23:21:27.420+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">JSR 303</category><category domain="http://www.blogger.com/atom/ns#">Hibernate Validator</category><category domain="http://www.blogger.com/atom/ns#">Bean Validation</category><category domain="http://www.blogger.com/atom/ns#">Spring</category><category domain="http://www.blogger.com/atom/ns#">SpEL</category><title>Putting a SpEL(l) on the Bean Validation API</title><description>&lt;p&gt;One of the new features introduced with version 3.0 of the &lt;a href="http://www.springsource.org/"&gt;Spring framework&lt;/a&gt; is the &lt;a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/expressions.html"&gt;Spring Expression Language&lt;/a&gt; or short "SpEL". This language is tailored for the needs when working with Spring and can be used when creating XML/annotation based Spring bean definitions for instance.&lt;/p&gt;&lt;p&gt;So I thought it would be nice if it was possible to use SpEL together with Hibernate Validator's &lt;a href="http://docs.jboss.org/hibernate/validator/4.1/api/org/hibernate/validator/constraints/ScriptAssert.html"&gt;@ScriptAssert&lt;/a&gt; constraint which allows to express validation routines using script or expression languages.&lt;/p&gt;&lt;p&gt;Unfortunately this does not work since currently no SpEL language binding for &lt;a href="http://jcp.org/en/jsr/detail?id=223"&gt;JSR 223&lt;/a&gt; ("Scripting for the Java&lt;sup&gt;TM&lt;/sup&gt; Platform") exists. As @ScriptAssert's validator uses JSR 223 for expression evaluation at least for now SpEL can't be used along with @ScriptAssert (there is an &lt;a href="https://jira.springframework.org/browse/SPR-7651"&gt;issue&lt;/a&gt; in Spring's JIRA addressing this problem).&lt;/p&gt;&lt;p&gt;But as shown in &lt;a href="http://musingsofaprogrammingaddict.blogspot.com/2009/02/getting-started-with-jsr-303-bean.html"&gt;previous&lt;/a&gt; &lt;a href="http://musingsofaprogrammingaddict.blogspot.com/2010/05/providing-bean-validation-support-for.html"&gt;posts&lt;/a&gt; it is very simple to create new constraint annotations for the Bean Validation API. So the idea is to build a new constraint @SpelAssert which resembles HV's @ScriptAssert but works with SpEL instead of the JSR 223 API.&lt;/p&gt;&lt;p&gt;Defining the annotation type is straight-forward:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;

&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@Target&lt;/span&gt;({ TYPE })&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@Retention&lt;/span&gt;(RUNTIME)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@Constraint&lt;/span&gt;(validatedBy = SpelAssertValidator.class)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@Documented&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="at"&gt;@interface&lt;/span&gt; SpelAssert {&lt;tt&gt;

&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pt"&gt;String&lt;/span&gt; message() &lt;span class="kw"&gt;default&lt;/span&gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;{de.gmorling.moapa.bvspel.SpelAssert.message}&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pt"&gt;Class&lt;/span&gt;&amp;lt;?&amp;gt;&lt;span class="ty"&gt;[]&lt;/span&gt; groups() &lt;span class="kw"&gt;default&lt;/span&gt; {};&lt;tt&gt;

&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pt"&gt;Class&lt;/span&gt;&amp;lt;? &lt;span class="di"&gt;extends&lt;/span&gt; Payload&amp;gt;&lt;span class="ty"&gt;[]&lt;/span&gt; payload() &lt;span class="kw"&gt;default&lt;/span&gt; {};&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pt"&gt;String&lt;/span&gt; value();&lt;tt&gt;

&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Besides the standard attributes &lt;code&gt;message()&lt;/code&gt;, &lt;code&gt;groups()&lt;/code&gt; and &lt;code&gt;payload()&lt;/code&gt; mandated by the BV specification we define one more attribute &lt;code&gt;value()&lt;/code&gt;, which takes the SpEL expression to evaluate.&lt;/p&gt;&lt;p&gt;Now let's come to the validator:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;

&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;

&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;

&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;SpelAssertValidator&lt;/span&gt; &lt;span class="di"&gt;implements&lt;/span&gt;&lt;tt&gt;

&lt;/tt&gt;ConstraintValidator&amp;lt;SpelAssert, &lt;span class="pt"&gt;Object&lt;/span&gt;&amp;gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Inject&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; ExpressionParser parser;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="pt"&gt;Expression&lt;/span&gt; expression;&lt;tt&gt;

&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; initialize(SpelAssert constraintAnnotation) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pt"&gt;String&lt;/span&gt; rawExpression = constraintAnnotation.value();&lt;tt&gt;

&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (rawExpression == &lt;span class="pc"&gt;null&lt;/span&gt;) {&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;throw&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ex"&gt;IllegalArgumentException&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;The expression specified in @&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;

&lt;/tt&gt;                + SpelAssert.class.getSimpleName() + &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt; must not be null.&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        expression = parser.parseExpression(rawExpression);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;

&lt;/tt&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;boolean&lt;/span&gt; isValid(&lt;span class="pt"&gt;Object&lt;/span&gt; value, ConstraintValidatorContext context) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (value == &lt;span class="pc"&gt;null&lt;/span&gt;) {&lt;tt&gt;

&lt;/tt&gt;            &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="pc"&gt;true&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="pt"&gt;Boolean&lt;/span&gt;.TRUE.equals(expression.getValue(value, &lt;span class="pt"&gt;Boolean&lt;/span&gt;.class));&lt;tt&gt;

&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;In &lt;code&gt;initialize()&lt;/code&gt; we use an &lt;a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/expression/ExpressionParser.html"&gt;ExpressionParser&lt;/a&gt; to parse the specified SpEL expression (so this happens only once) and evaluate the given object against it in &lt;code&gt;isValid()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;But wait a minute, where does the ExpressionParser come from, it is not instantiated here?&lt;/p&gt;&lt;p&gt;Right, the cool thing is Spring comes with it's own &lt;a href="http://download.oracle.com/javaee/6/api/javax/validation/ConstraintValidatorFactory.html"&gt;ConstraintValidatorFactory&lt;/a&gt; which performs dependency injection on constraint validators. A validator relying on that feature of course is not portable, but as this validator is based on SpEL and Spring anyways this is not an issue here.&lt;/p&gt;&lt;p&gt;In order to have this working a parser bean must be part of the Spring application context. We just register a &lt;a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/expression/spel/standard/SpelExpressionParser.html"&gt;SpelExpressionParser&lt;/a&gt;:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;

&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;

&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="ta"&gt;&amp;lt;beans&lt;/span&gt; &lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xmlns&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://www.springframework.org/schema/beans&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xmlns:xsi&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;

&lt;/tt&gt;    &lt;span class="an"&gt;xsi:schemaLocation&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://www.springframework.org/schema/beans&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="k"&gt;http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="an"&gt;id&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;parser&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="an"&gt;class&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;org.springframework.expression.spel.standard.SpelExpressionParser&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;

&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="an"&gt;id&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;validator&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="an"&gt;class&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;org.springframework.validation.beanvalidation.LocalValidatorFactoryBean&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;

&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;This context also shows how to provide a BV &lt;a href="http://download.oracle.com/javaee/6/api/javax/validation/Validator.html"&gt;Validator&lt;/a&gt; for dependency injection leveraging Spring's &lt;a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.html"&gt;LocalValidatorFactoryBean&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Now let's have a look at the @SpelAssert constraint in action. The following shows the canonical example of a class CalendarEvent where the start date shall always be earlier than the end date:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;

&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;

&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@SpelAssert&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;startDate &amp;lt; endDate&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;CalendarEvent&lt;/span&gt; {&lt;tt&gt;

&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="pt"&gt;Date&lt;/span&gt; startDate;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="pt"&gt;Date&lt;/span&gt; endDate;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;

&lt;/tt&gt;    &lt;span class="c"&gt;// getters, setters etc.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Note how SpEL allows dates to be compared using the "&amp;lt;" operator and that no alias for the evaluated bean is required, as all unqualified attribute/method names are resolved against the annotated object.&lt;/p&gt;&lt;p&gt;Finally we should have a test showing that the validator works as expected by validating a valid and an invalid CalendarEvent instance:&lt;/p&gt;&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;

&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;

&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;

&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;

&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;

&lt;/tt&gt;45&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@RunWith&lt;/span&gt;(SpringJUnit4ClassRunner.class)&lt;tt&gt;

&lt;/tt&gt;&lt;span class="at"&gt;@ContextConfiguration&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;SpelAssertTest&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Inject&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="pt"&gt;Validator&lt;/span&gt; validator;&lt;tt&gt;

&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="pt"&gt;Date&lt;/span&gt; startDate;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="pt"&gt;Date&lt;/span&gt; endDate;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Before&lt;/span&gt;&lt;tt&gt;

&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; setUpDates() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="pt"&gt;Calendar&lt;/span&gt; start = &lt;span class="pt"&gt;Calendar&lt;/span&gt;.getInstance();&lt;tt&gt;
&lt;/tt&gt;        start.set(&lt;span class="i"&gt;2010&lt;/span&gt;, &lt;span class="i"&gt;13&lt;/span&gt;, &lt;span class="i"&gt;24&lt;/span&gt;);&lt;tt&gt;

&lt;/tt&gt;        startDate = start.getTime();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="pt"&gt;Calendar&lt;/span&gt; end = &lt;span class="pt"&gt;Calendar&lt;/span&gt;.getInstance();&lt;tt&gt;
&lt;/tt&gt;        end.set(&lt;span class="i"&gt;2010&lt;/span&gt;, &lt;span class="i"&gt;13&lt;/span&gt;, &lt;span class="i"&gt;26&lt;/span&gt;);&lt;tt&gt;

&lt;/tt&gt;        endDate = end.getTime();&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Test&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; validEvent() {&lt;tt&gt;

&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        CalendarEvent event = &lt;span class="kw"&gt;new&lt;/span&gt; CalendarEvent();&lt;tt&gt;
&lt;/tt&gt;        event.setStartDate(startDate);&lt;tt&gt;
&lt;/tt&gt;        event.setEndDate(endDate);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        assertTrue(validator.validate(event).isEmpty());&lt;tt&gt;

&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Test&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; invalidEventYieldsConstraintViolation() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        CalendarEvent event = &lt;span class="kw"&gt;new&lt;/span&gt; CalendarEvent();&lt;tt&gt;

&lt;/tt&gt;        event.setStartDate(endDate);&lt;tt&gt;
&lt;/tt&gt;        event.setEndDate(startDate);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="pt"&gt;Set&lt;/span&gt;&amp;lt;ConstraintViolation&amp;lt;CalendarEvent&amp;gt;&amp;gt; violations = &lt;tt&gt;
&lt;/tt&gt;            validator.validate(event);&lt;tt&gt;

&lt;/tt&gt;        assertEquals(&lt;span class="i"&gt;1&lt;/span&gt;, violations.size());&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        ConstraintViolation&amp;lt;CalendarEvent&amp;gt; violation = &lt;tt&gt;
&lt;/tt&gt;            violations.iterator().next();&lt;tt&gt;
&lt;/tt&gt;        assertEquals(&lt;tt&gt;

&lt;/tt&gt;            &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;SpEL expression &lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;startDate &amp;lt; endDate&lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="k"&gt; didn't evaluate to true.&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;            violation.getMessage());&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;

&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;The complete sources for this post can be found at &lt;a href="https://github.com/gunnarmorling/musings-of-a-programming-addict/blob/master/bv-spel/"&gt;GitHub&lt;/a&gt;, so don't hesistate to give it a try or use it in your projects if you like. Any feedback or ideas for improvement are warmly welcome.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-9094520327516244949?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/cHG23Mel_u4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/cHG23Mel_u4/putting-spell-on-bean-validation-api.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>2</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/12/putting-spell-on-bean-validation-api.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-1607722207661764243</guid><pubDate>Wed, 17 Nov 2010 16:40:00 +0000</pubDate><atom:updated>2010-11-17T17:40:06.362+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">shell</category><category domain="http://www.blogger.com/atom/ns#">SVN</category><title>Identifying files with missing SVN properties</title><description>At my day job we are using the SVN property &lt;a href="http://svnbook.red-bean.com/nightly/en/svn.advanced.props.special.keywords.html"&gt;"svn:keywords"&lt;/a&gt; to let SVN replace the string "$Id$" with author name, revision number etc. within each Java source file.&lt;br /&gt;
&lt;br /&gt;
One can add this property automatically when creating new files with the help of SVN's &lt;a href="http://svnbook.red-bean.com/nightly/en/svn.advanced.props.html#svn.advanced.props.auto"&gt;auto props&lt;/a&gt; feature. But from time to time someone, e.g. a new developer not knowing about auto props, checks in files without having the "svn:keywords" property set.&lt;br /&gt;
&lt;br /&gt;
So I wondered how to identify such files in the repository. SVN doesn't provide a command answering that question, you only can retrieve all files having a certain property set.&lt;br /&gt;
&lt;br /&gt;
But no problem, some shell magic to the rescue:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tbody&gt;
&lt;tr&gt;   &lt;td class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }" title="click to toggle"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;   &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;comm -23 &amp;lt;(sort &amp;lt;(sed 's/\.\///g' &amp;lt;(find . -name "*.java"))) &amp;lt;(sort &amp;lt;(sed 's/ - Id//g' &amp;lt;(svn propget svn:keywords * -R)))&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br /&gt;
So what's happening here? The basic idea is to list those files &lt;i&gt;with&lt;/i&gt; the svn:keywords property set (&lt;a href="http://svnbook.red-bean.com/nightly/en/svn.ref.svn.c.propget.html"&gt;&lt;code&gt;svn propget&lt;/code&gt;&lt;/a&gt;) and compare this to a list with &lt;i&gt;all&lt;/i&gt; files (&lt;a href="http://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/find.1.html"&gt;&lt;code&gt;find&lt;/code&gt;&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
The outputs of both commands are brought into the same format using &lt;a href="http://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/sed.1.html"&gt;&lt;code&gt;sed&lt;/code&gt;&lt;/a&gt;, &lt;a href="http://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/sort.1.html"&gt;sorted&lt;/a&gt; and then passed as parameters to the &lt;a href="http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/comm.1.html"&gt;&lt;code&gt;comm&lt;/code&gt;&lt;/a&gt; command, which compares two input files to each other. The &lt;code&gt;-23&lt;/code&gt; parameter causes only those lines to be put out which are only contained in file1 but not in file2, which are exactly the names of those files lacking the "svn:keywords" property.&lt;br /&gt;
&lt;br /&gt;
I tested the command successfully on Mac OS X, but I think it should work pretty much the same way on other Unix systems, too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-1607722207661764243?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/_FjbDMXCQmw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/_FjbDMXCQmw/identifying-files-with-missing-svn.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>2</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/11/identifying-files-with-missing-svn.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-7599516641671899743</guid><pubDate>Sun, 15 Aug 2010 18:44:00 +0000</pubDate><atom:updated>2010-08-15T20:45:45.168+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">JDT</category><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">RCP</category><category domain="http://www.blogger.com/atom/ns#">Eclipse</category><title>Retrieving JDT sources with Eclipse 3.6</title><description>&lt;p&gt;While developing an Eclipse plug-in for a small spare-time project of mine I wondered where to find the sources of the &lt;a href="http://www.eclipse.org/jdt/"&gt;Java Development Tools&lt;/a&gt; (JDT). They used to be part of the Eclipse RCP/plug-in developers package in previous releases, but this isn't the case anymore with &lt;a href="http://www.eclipse.org/helios/"&gt;Eclipse 3.6 (Helios)&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;After some googling I found &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=322513"&gt;the&lt;/a&gt; &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=230357"&gt;reason&lt;/a&gt;: as of release 3.6 the RCP distribution (now named &lt;a href="http://www.eclipse.org/downloads/packages/eclipse-rcp-and-rap-developers/heliosr"&gt;"Eclipse for RCP and RAP Developers"&lt;/a&gt;) no longer contains any sources (except those for the actual platform plug-ins) in order to reduce the size of the download package.&lt;/p&gt;&lt;p&gt;If you want to get the sources for plug-ins such as JDT which are not part of the core platform you have to retrieve them separately. To do so you can use the new &lt;a href="http://archive.eclipse.org/eclipse/downloads/drops/S-3.6M7-201004291549/eclipse-news-M7.html#PDE"&gt;plug-in import wizard&lt;/a&gt; which allows to fetch source projects corresponding to plug-ins of the target platform directly from the Eclipse CVS.&lt;/p&gt;&lt;p&gt;Just open the "Plug-ins" view, right-click on the plug-in you want to retrieve (e.g. &lt;code&gt;org.eclipse.jdt.ui&lt;/code&gt;) and select "Import as" &gt; "Project from a Repository ...". Confirm the next dialog by clicking "Finish", and the check-out starts. Afterwards the new project will automatically replace the plug-in JAR as dependency in any dependent projects within your workspace. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-7599516641671899743?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/3_awMBFhqVE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/3_awMBFhqVE/retrieving-jdt-sources-with-eclipse-36.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>2</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/08/retrieving-jdt-sources-with-eclipse-36.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-6508639602789401411</guid><pubDate>Sat, 24 Jul 2010 12:41:00 +0000</pubDate><atom:updated>2010-07-25T17:55:07.718+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">Dependency Injection</category><category domain="http://www.blogger.com/atom/ns#">JSR 223</category><category domain="http://www.blogger.com/atom/ns#">JSR 299</category><category domain="http://www.blogger.com/atom/ns#">CDI</category><title>A CDI portable extension for JSR 223 scripting engines</title><description>&lt;p&gt;In the last couple of days I spent some time experimenting a little bit with &lt;a href="http://jcp.org/en/jsr/detail?id=299"&gt;CDI&lt;/a&gt;, the standard of the Java EE 6 platform for dependency injection services.&lt;/p&gt;

&lt;p&gt;I  must say that I really like that spec, as it hits the sweet spot between specifying features that provide a value out of the box (&lt;a href="http://docs.jboss.org/weld/reference/1.0.1-Final/en-US/html_single/#injection"&gt;type-safe DI&lt;/a&gt;, &lt;a href="http://docs.jboss.org/weld/reference/1.0.1-Final/en-US/html_single/#events"&gt;eventing&lt;/a&gt;, &lt;a href="http://docs.jboss.org/weld/reference/1.0.1-Final/en-US/html_single/#interceptors"&gt;interceptor services&lt;/a&gt; etc.) and being open enough to allow people to build totally new stuff based on it (using &lt;a href="http://docs.jboss.org/weld/reference/1.0.1-Final/en-US/html_single/#extend"&gt;portable extensions&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I've got the feeling we're going to see a lot of exciting things based on CDI within the near future. Actually this reminds me a bit of Java annotations. Having been introduced with Java 5, just over time people started using them for more and more use cases that had not been foreseen in the first place.&lt;/p&gt;

&lt;p&gt;Anyway, to do something practical with CDI I built a small portable extension which allows to retrieve &lt;a href="http://jcp.org/en/jsr/detail?id=223"&gt;JSR 223&lt;/a&gt; scripting engines using dependency injection.&lt;/p&gt;

&lt;p&gt;Just annotate any injection points of type &lt;code&gt;javax.script.ScriptEngine&lt;/code&gt; with one of the qualifier annotations &lt;code&gt;@Language&lt;/code&gt;, &lt;code&gt;@Extension&lt;/code&gt; or &lt;code&gt;@MimeType&lt;/code&gt;. The following code extract shows an example of a JavaScript engine (for example the &lt;a href="http://www.mozilla.org/rhino/"&gt;Rhino&lt;/a&gt; engine shipping with Java 6) being injected into some managed bean, where it can be used for arbitrary script evaluations:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@RequestScoped&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;MyBean&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Inject&lt;/span&gt; &lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Language&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;javascript&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) &lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; ScriptEngine jsEngine;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;// ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; foo() &lt;span class="di"&gt;throws&lt;/span&gt; ScriptException {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;assert&lt;/span&gt; &lt;span class="fl"&gt;42.0d&lt;/span&gt; == (&lt;span class="pt"&gt;Double&lt;/span&gt;)jsEngine.eval(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;2 * 21&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="c"&gt;// ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;The extension can be found in my &lt;a href="http://gunnarmorling-maven-repo.googlecode.com/svn/repo/de/gmorling/cdi/extensions/scripting-extension/"&gt;Maven repository&lt;/a&gt;. Just add the following dependency to your POM in order to use it:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="ta"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;de.gmorling.cdi.extensions&lt;span class="ta"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;scripting-extension&lt;span class="ta"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;0.1&lt;span class="ta"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;In case you want to take a look at the source code (which is just a few lines), you can check it out from &lt;a href="http://github.com/gunnarmorling/scripting-extension/"&gt;GitHub&lt;/a&gt;. As always, any ideas for improvement or other feedback are highly appreciated.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-6508639602789401411?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/794kGsSop8o" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/794kGsSop8o/cdi-portable-extension-for-jsr-223.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>0</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/07/cdi-portable-extension-for-jsr-223.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-4944153789806679201</guid><pubDate>Mon, 28 Jun 2010 21:33:00 +0000</pubDate><atom:updated>2010-07-12T00:15:57.036+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">JSR 303</category><category domain="http://www.blogger.com/atom/ns#">Hibernate Validator</category><category domain="http://www.blogger.com/atom/ns#">Bean Validation</category><category domain="http://www.blogger.com/atom/ns#">JSR 223</category><title>What's new in Hibernate Validator 4.1?</title><description>&lt;p&gt;I'm very proud to report that today &lt;a href="http://hibernate.org/hibernate/subprojects/validator.html"&gt;Hibernate Validator&lt;/a&gt; 4.1.0 Final has been &lt;a href="http://in.relation.to/Bloggers/HibernateValidator410FinalHasLanded"&gt;released&lt;/a&gt;. Besides many bug fixes this release adds also a lot of new features to the code base.&lt;/p&gt;

&lt;p&gt;The changes fall into four areas, which I'm going to discuss in detail in the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New constraint annotations&lt;/li&gt;
&lt;li&gt;ResourceBundleLocator API&lt;/li&gt;
&lt;li&gt;API for programmatic constraint creation&lt;/li&gt;
&lt;li&gt;Constraint annotation processor&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;New constraint annotations&lt;/h2&gt;

&lt;p&gt;In addition to the constraints defined in the Bean Validation spec and those custom constraints already part of HV 4.0, the new release ships with the following new constraint annotations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://docs.jboss.org/hibernate/stable/validator/api/org/hibernate/validator/constraints/CreditCardNumber.html"&gt;@CreditCardNumber&lt;/a&gt;: Validates that a given String represents a valid credit card number using the Luhn algorithm. Useful to detect mis-entered numbers for instance.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://docs.jboss.org/hibernate/stable/validator/api/org/hibernate/validator/constraints/NotBlank.html"&gt;@NotBlank&lt;/a&gt;: Validates that a given String is neither null nor empty nor contains only whitespaces.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://docs.jboss.org/hibernate/stable/validator/api/org/hibernate/validator/constraints/URL.html"&gt;@URL&lt;/a&gt;: Validates that a given String is a valid URL. Can be restricted to certain protocols if required: &lt;code&gt;@URL(protocol = "http") private String url;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://docs.jboss.org/hibernate/stable/validator/api/org/hibernate/validator/constraints/ScriptAssert.html"&gt;@ScriptAssert&lt;/a&gt;: Allows to use scripting or expression languages for the definition of class-level validation routines.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's have a closer look at the @ScriptAssert constraint, which I'm particularly excited about as I have implemented it :-). &lt;/p&gt;

&lt;p&gt;The intention behind it is to provide a simplified way for expressing validation logic that is based on multiple attributes of a given type. Instead of having to implement dedicated class-level constraints the @ScriptAssert constraint allows to express such validation routines in an ad hoc manner using a wide range of scripting and expression languages.&lt;/p&gt;

&lt;p&gt;In order to use this constraint an implementation of the Java Scripting API as defined by &lt;a href="http://jcp.org/en/jsr/detail?id=223"&gt;JSR 223&lt;/a&gt; ("Scripting for the Java&lt;sup&gt;TM&lt;/sup&gt; Platform") must be part of the class path. This is automatically the case when running on Java 6. For older Java versions, the JSR 223 RI can be added manually to the class path.&lt;/p&gt;

&lt;p&gt;As example let's consider a class representing calendar events. The start date of such an event shall always be earlier than the end date. Using JavaScript (for which an engine comes with Java 6) this requirement could be expressed as follows:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@ScriptAssert&lt;/span&gt;(lang = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;javascript&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, script = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;_this.startDate.before(_this.endDate)&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;CalendarEvent&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="pt"&gt;Date&lt;/span&gt; startDate;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="pt"&gt;Date&lt;/span&gt; endDate;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;//...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;So all you have to do is to specify a scripting expression returning true or false within the &lt;code&gt;script&lt;/code&gt; attribute. The expression must be implemented in the language given within the &lt;code&gt;language&lt;/code&gt; attribute. The language name must be the language's name as registered with the JSR 223 &lt;a href="http://java.sun.com/javase/6/docs/api/javax/script/ScriptEngineManager.html"&gt;ScriptEngineManager&lt;/a&gt;. Within the expression the annotated element can be accessed using the alias &lt;code&gt;_this&lt;/code&gt; by default.&lt;/p&gt;

&lt;p&gt;The cool thing is that the @ScriptConsert constraint can be used with any other scripting language for which a JSR 223 binding exists. Let's take &lt;a href="http://commons.apache.org/jexl/"&gt;JEXL&lt;/a&gt; from the Apache Commons project for instance. Using Maven you only have to add the following dependency:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="ta"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.commons&lt;span class="ta"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;commons-jexl&lt;span class="ta"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0.1&lt;span class="ta"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;With JEXL dates can be compared using the "&amp;lt;" operator. Using a shorter alias for the evaluated object the constraint from above therefore can be rewritten as follows:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@ScriptAssert&lt;/span&gt;(lang = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;jexl&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, script = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;_.startDate &amp;lt; _.endDate&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, alias = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;CalendarEvent&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="pt"&gt;Date&lt;/span&gt; startDate;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="pt"&gt;Date&lt;/span&gt; endDate;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;//...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Very likely one will work with only one scripting language throughout all @ScriptAssert constraints of an application. So let's leverage the power of constraint composition to create a custom constraint which allows for an even more compact notation by setting the attributes &lt;code&gt;lang&lt;/code&gt; and &lt;code&gt;alias&lt;/code&gt; to fixed values: &lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@Target&lt;/span&gt;({ TYPE })&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@Retention&lt;/span&gt;(RUNTIME)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@Constraint&lt;/span&gt;(validatedBy = {})&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@Documented&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@ScriptAssert&lt;/span&gt;(lang = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;jexl&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, script = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, alias = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="at"&gt;@interface&lt;/span&gt; JexlAssert {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pt"&gt;String&lt;/span&gt; message() &lt;span class="kw"&gt;default&lt;/span&gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;{org.hibernate.validator.constraints.ScriptAssert.message}&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pt"&gt;Class&lt;/span&gt;&amp;lt;?&amp;gt;&lt;span class="ty"&gt;[]&lt;/span&gt; groups() &lt;span class="kw"&gt;default&lt;/span&gt; {};&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pt"&gt;Class&lt;/span&gt;&amp;lt;? &lt;span class="di"&gt;extends&lt;/span&gt; Payload&amp;gt;&lt;span class="ty"&gt;[]&lt;/span&gt; payload() &lt;span class="kw"&gt;default&lt;/span&gt; {};&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@OverridesAttribute&lt;/span&gt;(constraint = ScriptAssert.class, name = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pt"&gt;String&lt;/span&gt; value();&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Note how the &lt;code&gt;script&lt;/code&gt; attribute of the composing @ScriptAssert constraint is overridden using the &lt;a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/api/javax/validation/OverridesAttribute.html"&gt;@OverridesAttribute&lt;/a&gt; meta-annotation. Using this custom constraint the example finally reads as follows:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@JexlAssert&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;_.startDate &amp;lt; _.endDate&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;CalendarEvent&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="pt"&gt;Date&lt;/span&gt; startDate;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="pt"&gt;Date&lt;/span&gt; endDate;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;//...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;As shown the @ScriptAssert constraint allows to define class-level constraints in a very compact way. &lt;/p&gt;

&lt;p&gt;But there is also a price to pay. As scripting languages are used, compile-time type-safety is lost. When for instance the &lt;code&gt;startDate&lt;/code&gt; attribute is renamed the script expression would have to be adapted by hand. Also evaluation performance should be considered when validation logic is getting more complex. &lt;/p&gt;

&lt;p&gt;So I recommend to try it out and choose what ever fits your needs best.&lt;/p&gt;

&lt;h2&gt;The ResourceBundleLocator API&lt;/h2&gt;

&lt;p&gt;The Bean Validation API defines the &lt;a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/api/javax/validation/MessageInterpolator.html"&gt;MessageInterpolator&lt;/a&gt; interface which allows to plug in custom strategies for message interpolation and resource bundle loading. &lt;/p&gt;

&lt;p&gt;As it turned out, most users only want to customize the latter aspect (e.g. in order to load message bundles from a database) but would like to re-use the interpolation algorithm provided by Hibernate Validator.&lt;/p&gt;

&lt;p&gt;Therefore Hibernate Validator 4.1 introduces the interface &lt;a href="http://docs.jboss.org/hibernate/stable/validator/api/org/hibernate/validator/resourceloading/ResourceBundleLocator.html"&gt;ResourceBundleLocator&lt;/a&gt; which is used by HV's default MessageInterpolator implementation &lt;a href="http://docs.jboss.org/hibernate/stable/validator/api/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.html"&gt;ResourceBundleMessageInterpolator&lt;/a&gt; to do the actual resource bundle loading.&lt;/p&gt;

&lt;p&gt;The interface defines only one method, in which implementations have to return the bundle for a given locale:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;interface&lt;/span&gt; &lt;span class="cl"&gt;ResourceBundleLocator&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pt"&gt;ResourceBundle&lt;/span&gt; getResourceBundle(&lt;span class="pt"&gt;Locale&lt;/span&gt; locale);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;The ResourceBundleLocator to be used can be set when creating a &lt;a href="http://download.oracle.com/docs/cd/E17410_01/javaee/6/api/javax/validation/ValidatorFactory.html"&gt;ValidatorFactory&lt;/a&gt;:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;ValidatorFactory validatorFactory = Validation&lt;tt&gt;
&lt;/tt&gt;    .byProvider(HibernateValidator.class)&lt;tt&gt;
&lt;/tt&gt;    .configure()&lt;tt&gt;
&lt;/tt&gt;    .messageInterpolator(&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;new&lt;/span&gt; ResourceBundleMessageInterpolator(&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;new&lt;/span&gt; MyCustomResourceBundleLocator()))&lt;tt&gt;
&lt;/tt&gt;    .buildValidatorFactory();&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;The default ResourceBundleLocator implementation used by Hibernate Validator is &lt;a href="http://docs.jboss.org/hibernate/stable/validator/api/org/hibernate/validator/resourceloading/PlatformResourceBundleLocator.html"&gt;PlatformResourceBundleLocator&lt;/a&gt; which simply loads bundles using &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/ResourceBundle.html#getBundle(java.lang.String)"&gt;ResourceBundle.loadBundle()&lt;/a&gt;. Another implementation provided out of the box is &lt;a href="http://docs.jboss.org/hibernate/stable/validator/api/org/hibernate/validator/resourceloading/AggregateResourceBundleLocator.html"&gt;AggregateResourceBundleLocator&lt;/a&gt;, which allows to retrieve message texts from multiple bundles by merging them into a single aggregate bundle. Let's look at an example:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;HibernateValidatorConfiguration configuration = Validation&lt;tt&gt;
&lt;/tt&gt;    .byProvider(HibernateValidator.class)&lt;tt&gt;
&lt;/tt&gt;    .configure();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;ValidatorFactory validatorFactory = configuration&lt;tt&gt;
&lt;/tt&gt;    .messageInterpolator(&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;new&lt;/span&gt; ResourceBundleMessageInterpolator(&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;new&lt;/span&gt; AggregateResourceBundleLocator(&lt;tt&gt;
&lt;/tt&gt;                &lt;span class="pt"&gt;Arrays&lt;/span&gt;.asList(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;), &lt;tt&gt;
&lt;/tt&gt;                configuration.getDefaultResourceBundleLocator())))&lt;tt&gt;
&lt;/tt&gt;    .buildValidatorFactory();&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Here messages from bundles "foo" and "bar" could be used in constraints. In case the same key was contained in both bundles, the value from bundle "foo" would have precedence, as it comes first in the list. If a given key can't be found in any of the two bundles as fallback the default locator (which provides access to the ValidationMessages bundle as demanded by the JSR 303 spec) will be tried.&lt;/p&gt;

&lt;h2&gt;API for programmatic constraint creation&lt;/h2&gt;

&lt;p&gt;Using the Bean Validation API constraints can be declared using either annotations and/or XML descriptor files. Hibernate Validator 4.1 introduces a third approach by providing an API for &lt;a href="http://docs.jboss.org/hibernate/validator/4.1/reference/en-US/html/programmaticapi.html"&gt;programmatic constraint declaration&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;This API can come in handy for instance in dynamic scenarios where constraints change upon runtime or for testing scenarios.&lt;/p&gt;

&lt;p&gt;As example let's consider two classes, &lt;code&gt;Customer&lt;/code&gt; and &lt;code&gt;Order&lt;/code&gt;, from a web shop application for which the following constraints shall apply:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;each customer must have a name&lt;/li&gt;
&lt;li&gt;each order must have a customer&lt;/li&gt;
&lt;li&gt;each order must comprise at least one order line&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With help of the programmatic constraint API these constraints can be declared as follows:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;ConstraintMapping mapping = &lt;span class="kw"&gt;new&lt;/span&gt; ConstraintMapping();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;mapping&lt;tt&gt;
&lt;/tt&gt;    .type(Order.class)&lt;tt&gt;
&lt;/tt&gt;        .property(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;customer&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="pt"&gt;ElementType&lt;/span&gt;.FIELD)&lt;tt&gt;
&lt;/tt&gt;            .constraint(NotNullDef.class)&lt;tt&gt;
&lt;/tt&gt;        .property(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;orderLines&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="pt"&gt;ElementType&lt;/span&gt;.FIELD)&lt;tt&gt;
&lt;/tt&gt;            .constraint(SizeDef.class)&lt;tt&gt;
&lt;/tt&gt;                .min(&lt;span class="i"&gt;1&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;                .message(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;An order must contain at least one order line&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    .type(Customer.class)&lt;tt&gt;
&lt;/tt&gt;        .property(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="pt"&gt;ElementType&lt;/span&gt;.FIELD)&lt;tt&gt;
&lt;/tt&gt;            .constraint(NotNullDef.class);  &lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;As the listing shows the API is designed in a fluent style with the class &lt;a href="http://docs.jboss.org/hibernate/validator/4.1/api/org/hibernate/validator/cfg/ConstraintMapping.html"&gt;ConstraintMapping&lt;/a&gt; as entry point. Constraints are declared by chaining method calls which specify to which property of which type which constraints should be added.&lt;/p&gt;

&lt;p&gt;The API provides constraint definition classes such as &lt;a href="http://docs.jboss.org/hibernate/validator/4.1/api/org/hibernate/validator/cfg/defs/NotNullDef.html"&gt;NotNullDef&lt;/a&gt; etc. for all built-in constraints, which allow to access their properties (min(), message() etc.) in a type-safe way. For custom constraints you could either provide your own constraint definition class or you could make use of &lt;a href="http://docs.jboss.org/hibernate/validator/4.1/api/org/hibernate/validator/cfg/defs/GenericConstraintDef.html"&gt;GenericConstraintDef&lt;/a&gt; which allows to identify properties by name.&lt;/p&gt;

&lt;p&gt;Having created a constraint mapping it has to be registered with the constraint validator factory. As the programmatic API is not part of the Bean Validation spec, we must explicitely specify Hibernate Validator as the BV provider to be used:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="pt"&gt;Validator&lt;/span&gt; validator = Validation&lt;tt&gt;
&lt;/tt&gt;    .byProvider(HibernateValidator.class)&lt;tt&gt;
&lt;/tt&gt;    .configure()&lt;tt&gt;
&lt;/tt&gt;    .addMapping(mapping)&lt;tt&gt;
&lt;/tt&gt;    .buildValidatorFactory()&lt;tt&gt;
&lt;/tt&gt;    .getValidator();&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;If you now use this validator to validate an &lt;code&gt;Order&lt;/code&gt; object which has no customer set a constraint violation will occur, just as if the "customer" property was annotated with @NotNull.&lt;/p&gt;

&lt;h2&gt;Constraint annotation processor&lt;/h2&gt;

&lt;p&gt;The Hibernate Validator annotation processor might become your new favourite tool if you find yourself accidentally doing things like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;annotating Strings with @Min to specify a minimum length (instead of using @Size)&lt;/li&gt;
&lt;li&gt;annotating the setter of a JavaBean property (instead of the getter method)&lt;/li&gt;
&lt;li&gt;annotating static fields/methods with constraint annotations (which is not supported)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Normally you would notice such mistakes only during run-time. The annotation processor helps in saving your valuable time by detecting these and similar errors already upon compile-time by plugging into the build process and raising compilation errors whenever constraint annotations are incorrectly used.&lt;/p&gt;

&lt;p&gt;The processor can be used in basically every build environment (plain &lt;a href="http://java.sun.com/javase/6/docs/technotes/guides/javac/index.html"&gt;javac&lt;/a&gt;, Apache &lt;a href="http://ant.apache.org/"&gt;Ant&lt;/a&gt;, Apache &lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt;) as well as within all common IDEs. Just be sure to use JDK 6 or later, as the processor is based on the "Pluggable Annotation Processing API" defined by &lt;a href="http://jcp.org/en/jsr/detail?id=269"&gt;JSR 269&lt;/a&gt; which was introduced with Java 6.&lt;/p&gt;

&lt;p&gt;The HV reference guide &lt;a href="http://docs.jboss.org/hibernate/validator/4.1/reference/en-US/html/ch08.html#d0e2816"&gt;describes in detail&lt;/a&gt; how to integrate the processor into the different environments, so I'll spare you the details here. As example the following screenshot shows some compilation errors raised by the processor within the Eclipse IDE (click to enlarge):&lt;/p&gt;

&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Ams_WxvNvnk/TDo8NYa_ShI/AAAAAAAAABQ/3R6zP6bqSSY/s1600/annotation_processor_eclipse.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 285px;" src="http://1.bp.blogspot.com/_Ams_WxvNvnk/TDo8NYa_ShI/AAAAAAAAABQ/3R6zP6bqSSY/s400/annotation_processor_eclipse.png" border="0" alt="Hibernate Validator Annotation Processor in Eclipse IDE" id="BLOGGER_PHOTO_ID_5492768896123357714" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just for the record it should be noted that the annotation processor already works pretty well but is currently still under development and is considered as an experimental feature as of HV 4.1. If you are facing any problems please report them in &lt;a href="http://opensource.atlassian.com/projects/hibernate/browse/HV/component/10356"&gt;JIRA&lt;/a&gt;. Some &lt;a href="http://docs.jboss.org/hibernate/validator/4.1/reference/en-US/html/ch08.html#section-known-issues"&gt;known issues&lt;/a&gt; are also discussed in the reference guide.&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;The focus for Hibernate Validator 4.0 was to provide a feature-complete, production-ready reference implementation of the &lt;a href="http://jcp.org/en/jsr/detail?id=303"&gt;Bean Validation&lt;/a&gt; spec.&lt;/p&gt;

&lt;p&gt;While strictly staying spec-compliant, HV 4.1 goes beyond what is defined in JSR 303 and aims at generating even more user value by providing new constraints, new API functionality as well as an annotation processor for compile-time annotation checking.&lt;/p&gt;

&lt;p&gt;In order to try out the new features yourself just download the release from &lt;a href="https://sourceforge.net/projects/hibernate/files/hibernate-validator/4.1.0.Final"&gt;SourceForge&lt;/a&gt;. Of course HV 4.1 can also be retrieved from the JBoss Maven &lt;a href="https://repository.jboss.org/nexus/content/repositories/public/org/hibernate/hibernate-validator/4.1.0.Final"&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you are already using HV 4.0.x, the new release generally should work as drop-in replacement. The only exception is that we had to move the class &lt;a href="http://docs.jboss.org/hibernate/validator/4.1/api/org/hibernate/validator/messageinterpolation/ResourceBundleMessageInterpolator.html"&gt;ResourceBundleMessageInterpolator&lt;/a&gt; to the new package &lt;code&gt;messageinterpolation&lt;/code&gt;. So if you're directly referencing this class, you'll have to update your imports here.&lt;/p&gt;

&lt;p&gt;The rationale behind this relocation was to clearly separate those packages which can safely be accessed by HV users from packages intended for internal use only. The public packages are: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;org.hibernate.validator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org.hibernate.validator.cfg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org.hibernate.validator.constraints&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org.hibernate.validator.messageinterpolation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;org.hibernate.validator.resourceloading&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course we'd be very happy on any feedback. Questions and comments can be posted in the &lt;a href="http://forum.hibernate.org/viewforum.php?f=9"&gt;HV forum&lt;/a&gt;, while any issues or feature requests should be reported in &lt;a href="http://opensource.atlassian.com/projects/hibernate/browse/HV"&gt;JIRA&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-4944153789806679201?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/BqKFCzI8PcU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/BqKFCzI8PcU/whats-new-in-hibernate-validator-41.html</link><author>noreply@blogger.com (Gunnar Morling)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_Ams_WxvNvnk/TDo8NYa_ShI/AAAAAAAAABQ/3R6zP6bqSSY/s72-c/annotation_processor_eclipse.png" height="72" width="72" /><thr:total>11</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/06/whats-new-in-hibernate-validator-41.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-4922406893500601982</guid><pubDate>Sat, 12 Jun 2010 21:42:00 +0000</pubDate><atom:updated>2010-06-13T09:31:06.133+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">XPath</category><category domain="http://www.blogger.com/atom/ns#">XML</category><category domain="http://www.blogger.com/atom/ns#">Oracle</category><title>Oracle's extractValue() Function and XML Namespaces</title><description>&lt;p&gt;With the help of &lt;a href="http://www.oracle.com/technology/software/products/database/index.html"&gt;Oracle's&lt;/a&gt; &lt;a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/functions059.htm#SQLRF06173"&gt;extractValue()&lt;/a&gt; function one can retrieve values from XML documents stored in a database using &lt;a href="http://www.w3.org/TR/xpath/"&gt;XPath&lt;/a&gt; expressions.&lt;/p&gt;

&lt;p&gt;Generally this function works as expected but it gave me a hard time when &lt;a href="http://www.w3.org/TR/xml-names/"&gt;XML namespaces&lt;/a&gt; came into play. As I didn't find much related information on the web I thought a short example might be helpful for others facing the same problem.&lt;/p&gt;

&lt;p&gt;Let's take the web service from the video rental shop from my recent post &lt;a href="http://musingsofaprogrammingaddict.blogspot.com/2010/02/integrating-jax-ws-with-xmlbeans.html"&gt;Integrating JAX-WS with XmlBeans&lt;/a&gt; as example. &lt;/p&gt;

&lt;p&gt;For auditing purposes all requests and responses of the web service might be logged in a database table &lt;code&gt;REQUESTS&lt;/code&gt; created as follows:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="r"&gt;CREATE&lt;/span&gt; &lt;span class="r"&gt;TABLE&lt;/span&gt; &lt;span class=""&gt;REQUESTS&lt;/span&gt; (&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=""&gt;ID&lt;/span&gt; &lt;span class=""&gt;NUMBER&lt;/span&gt;(&lt;span class="i"&gt;10&lt;/span&gt;,&lt;span class="i"&gt;0&lt;/span&gt;) &lt;span class="r"&gt;PRIMARY&lt;/span&gt; &lt;span class="r"&gt;KEY&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=""&gt;REQUEST&lt;/span&gt; &lt;span class=""&gt;XMLTYPE&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=""&gt;RESPONSE&lt;/span&gt; &lt;span class=""&gt;XMLTYPE&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;);&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt; 

&lt;p&gt;In reality, logging would probably be implemented using a &lt;a href="https://jax-ws.dev.java.net/articles/handlers_introduction.html"&gt;message handler&lt;/a&gt;, but for demonstration purposes let's simply insert a sample request of the FindMoviesByDirector() operation using SQL:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="r"&gt;INSERT&lt;/span&gt; &lt;span class="r"&gt;INTO&lt;/span&gt; &lt;span class=""&gt;REQUESTS&lt;/span&gt; (&lt;span class=""&gt;ID&lt;/span&gt;, &lt;span class=""&gt;REQUEST&lt;/span&gt;, &lt;span class=""&gt;RESPONSE&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;VALUES&lt;/span&gt; (&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="i"&gt;1&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;&amp;lt;soapenv:Envelope &lt;tt&gt;
&lt;/tt&gt;        xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; &lt;tt&gt;
&lt;/tt&gt;        xmlns:typ=&amp;quot;http://www.gunnarmorling.de/moapa/videorental/types&amp;quot;&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &amp;lt;soapenv:Header/&amp;gt;&lt;tt&gt;
&lt;/tt&gt;        &amp;lt;soapenv:Body&amp;gt;&lt;tt&gt;
&lt;/tt&gt;            &amp;lt;typ:FindMoviesByDirectorRequest&amp;gt;&lt;tt&gt;
&lt;/tt&gt;                &amp;lt;Director&amp;gt;Bryan Singer&amp;lt;/Director&amp;gt;&lt;tt&gt;
&lt;/tt&gt;            &amp;lt;/typ:FindMoviesByDirectorRequest&amp;gt;&lt;tt&gt;
&lt;/tt&gt;        &amp;lt;/soapenv:Body&amp;gt;&lt;tt&gt;
&lt;/tt&gt;     &amp;lt;/soapenv:Envelope&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Here we have two namespace aliases declared, &lt;code&gt;soapenv&lt;/code&gt; for the &lt;a href="http://www.w3.org/TR/soap/"&gt;SOAP&lt;/a&gt; message and &lt;code&gt;typ&lt;/code&gt; for the actual message content.&lt;/p&gt;

&lt;p&gt;The key for accessing values from this document using extractValue() is the pretty poorly documented optional parameter &lt;code&gt;namespace_string&lt;/code&gt;, which can be used to declare any namespaces. This has to happen in the form &lt;code&gt;xmlns:alias="URI"&lt;/code&gt;, multiple namespaces must be separated by a space character. &lt;/p&gt;

&lt;p&gt;Knowing that, it's easy to issue a SQL query which retrieves the director name from the request above. Just make sure to qualify the element names with their namespace alias in the XPath expression:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="r"&gt;SELECT&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=""&gt;req&lt;/span&gt;.&lt;span class=""&gt;id&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=""&gt;extractValue&lt;/span&gt;(&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=""&gt;req&lt;/span&gt;.&lt;span class=""&gt;request&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/soapenv:Envelope/soapenv:Body/typ:FindMoviesByDirectorRequest/Director&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;xmlns:soapenv=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:typ=&amp;quot;http://www.gunnarmorling.de/moapa/videorental/types&amp;quot;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;) &lt;span class=""&gt;Title&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;FROM&lt;/span&gt; &lt;tt&gt;
&lt;/tt&gt;    &lt;span class=""&gt;requests&lt;/span&gt; &lt;span class=""&gt;req&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;WHERE&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=""&gt;id&lt;/span&gt; = &lt;span class="i"&gt;1&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=""&gt;ID&lt;/span&gt;   &lt;span class=""&gt;TITLE&lt;/span&gt; &lt;tt&gt;
&lt;/tt&gt;---------------&lt;span class="c"&gt;--&lt;tt&gt;
&lt;/tt&gt;1    Bryan Singer&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-4922406893500601982?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/rjj3x-jLHk0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/rjj3x-jLHk0/oracles-extractvalue-function-and-xml.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>13</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/06/oracles-extractvalue-function-and-xml.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-5974115482043732340</guid><pubDate>Fri, 14 May 2010 21:10:00 +0000</pubDate><atom:updated>2010-05-15T11:14:44.617+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">JSR 303</category><category domain="http://www.blogger.com/atom/ns#">Joda Time API</category><category domain="http://www.blogger.com/atom/ns#">Bean Validation</category><title>Providing Bean Validation Support for the Joda Time API</title><description>&lt;p&gt;Amongst others the &lt;a href="http://jcp.org/en/jsr/detail?id=303"&gt;Bean Validation&lt;/a&gt; API defines two constraint annotations related to time: &lt;a href="http://java.sun.com/javaee/6/docs/api/javax/validation/constraints/Past.html"&gt;@Past&lt;/a&gt; and &lt;a href="http://java.sun.com/javaee/6/docs/api/javax/validation/constraints/Future.html"&gt;@Future&lt;/a&gt;. With the help of these constraints one can validate that a given element is a date either in the past or in the future.&lt;/p&gt;

&lt;p&gt;As per the BV specification these constraints are allowed for the types &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Date.html"&gt;java.util.Date&lt;/a&gt; and &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/Calendar.html"&gt;java.util.Calendar&lt;/a&gt;. But what if you are working with an alternative date/time library such as the &lt;a href="http://joda-time.sourceforge.net/"&gt;Joda Time API&lt;/a&gt;? Does that mean you can't use the @Past/@Future constraints?&lt;/p&gt;

&lt;p&gt;Luckily not, as the Bean Validation API defines a mechanism for adding new validators to existing constraints. Basically all you have to do is to implement a validator for each type to be supported and register it within a constraint mapping file.&lt;/p&gt;

&lt;p&gt;Note that for the remainder of this post I'll focus on the @Past constraint. Doing the same for @Future is left as an exercise for the reader.&lt;/p&gt;

&lt;h2&gt;Providing a Validator&lt;/h2&gt;

&lt;p&gt;So let's start with implementing a validator. The Joda Time API provides a whole bunch of types replacing the JDK date and time types. A good introduction to these types can be found in Joda's &lt;a href="http://joda-time.sourceforge.net/quickstart.html"&gt;quickstart guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All Joda types representing exact points on the time-line implement the interface &lt;a href="http://joda-time.sourceforge.net/api-release/org/joda/time/ReadableInstant.html"&gt;ReadableInstant&lt;/a&gt;. Providing an @Past validator for that interface will allow the @Past constraint to be used for widely used ReadableInstant implementations such as &lt;a href="http://joda-time.sourceforge.net/api-release/org/joda/time/DateTime.html"&gt;DateTime&lt;/a&gt; or &lt;a href="http://joda-time.sourceforge.net/api-release/org/joda/time/DateMidnight.html"&gt;DateMidnight&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Implementing the validator is straight-forward. Obeying the contract defined by @Past the given date is simply compared to a new DateTime instance which represents the current instant in the default time zone:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;PastValidatorForReadableInstant&lt;/span&gt; &lt;span class="di"&gt;implements&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        ConstraintValidator&amp;lt;Past, ReadableInstant&amp;gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; initialize(Past constraintAnnotation) {}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;boolean&lt;/span&gt; isValid(ReadableInstant value,&lt;tt&gt;
&lt;/tt&gt;            ConstraintValidatorContext constraintValidatorContext) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;if&lt;/span&gt;(value == &lt;span class="kw"&gt;null&lt;/span&gt;) {&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;true&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; value.isBefore(&lt;span class="kw"&gt;new&lt;/span&gt; DateTime());&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Similar validators could also be written for other Joda types which don't implement ReadableInstant (such as &lt;a href="http://joda-time.sourceforge.net/api-release/org/joda/time/LocalDate.html"&gt;LocalDate&lt;/a&gt;) but as this is basically the same, it is out of the scope of this post.&lt;/p&gt;

&lt;h2&gt;Registering the Validator&lt;/h2&gt;

&lt;p&gt;Having implemented the validator we need to register it within a &lt;a href="http://docs.jboss.org/hibernate/stable/validator/reference/en/html_single/#d0e1957"&gt;constraint mapping&lt;/a&gt; file:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="ta"&gt;&amp;lt;constraint-mappings&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xmlns&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://jboss.org/xml/ns/javax/validation/mapping&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xmlns:xsi&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xsi:schemaLocation&lt;/span&gt;=&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;constraint-definition&lt;/span&gt; &lt;span class="an"&gt;annotation&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;javax.validation.constraints.Past&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ta"&gt;&amp;lt;validated-by&lt;/span&gt; &lt;span class="an"&gt;include-existing-validators&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;             &lt;span class="ta"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;de.gmorling.moapa.joda_bv_integration.PastValidatorForReadableInstant&lt;span class="ta"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ta"&gt;&amp;lt;/validated-by&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;/constraint-definition&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/constraint-mappings&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Using the &lt;code&gt;validated-by&lt;/code&gt; element we add our new validator to the validators for the @Past constraint. By setting &lt;code&gt;include-existing-validators&lt;/code&gt; to true, we ensure that the @Past constraint still can be used at the JDK date types.&lt;/p&gt;

&lt;p&gt;As demanded by the Bean Validation API we then register the constraint mapping file within the central configuration file validation.xml:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="pp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;validation-config&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xmlns&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://jboss.org/xml/ns/javax/validation/configuration&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xmlns:xsi&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xsi:schemaLocation&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.0.xsd&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;constraint-mapping&amp;gt;&lt;/span&gt;META-INF/validation/custom-constraints.xml&lt;span class="ta"&gt;&amp;lt;/constraint-mapping&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/validation-config&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;h2&gt;Trying it out&lt;/h2&gt;

&lt;p&gt;Now it's time to test how that all works out. To do so, we define an examplary domain class Customer which has an attribute birthday of the Joda type DateMidnight:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Customer&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;final&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; name;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;final&lt;/span&gt; DateMidnight birthday;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; Customer(&lt;span class="ty"&gt;String&lt;/span&gt; name, DateMidnight birthday) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.name = name;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.birthday = birthday;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@NotNull&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; getName() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; name;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@NotNull&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Past&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; DateMidnight getBirthday() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; birthday;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;A simple test finally shows that creating a customer with a future birthday causes a constraint violation, while a customer with a birthday in the past doesn't:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;CustomerTest&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;Validator&lt;/span&gt; validator;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@BeforeClass&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; setUpValidatorAndDates() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();&lt;tt&gt;
&lt;/tt&gt;        validator = validatorFactory.getValidator();&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Test&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; customerWithFutureBirthdayCausesConstraintViolation() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        Customer customer = &lt;span class="kw"&gt;new&lt;/span&gt; Customer(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="kw"&gt;new&lt;/span&gt; DateMidnight(&lt;span class="i"&gt;2020&lt;/span&gt;, &lt;span class="i"&gt;11&lt;/span&gt;, &lt;span class="i"&gt;3&lt;/span&gt;));&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ty"&gt;Set&lt;/span&gt;&amp;lt;ConstraintViolation&amp;lt;Customer&amp;gt;&amp;gt; constraintViolations = validator.validate(customer);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        assertEquals(&lt;span class="i"&gt;1&lt;/span&gt;, constraintViolations.size());&lt;tt&gt;
&lt;/tt&gt;        assertEquals(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;must be in the past&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, constraintViolations.iterator().next().getMessage());&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Test&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; customerWithPastBirthdayCausesNoConstraintViolation() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        Customer customer = &lt;span class="kw"&gt;new&lt;/span&gt; Customer(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="kw"&gt;new&lt;/span&gt; DateMidnight(&lt;span class="i"&gt;1960&lt;/span&gt;, &lt;span class="i"&gt;11&lt;/span&gt;, &lt;span class="i"&gt;3&lt;/span&gt;));&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ty"&gt;Set&lt;/span&gt;&amp;lt;ConstraintViolation&amp;lt;Customer&amp;gt;&amp;gt; constraintViolations = validator.validate(customer);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        assertTrue(constraintViolations.isEmpty());&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;The complete source code in form of a Maven project can be found in my &lt;a href="http://github.com/gunnarmorling/musings-of-a-programming-addict/tree/master/joda-bv-integration/"&gt;Git repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So just try it out and don't hesistate to post any feedback. It is also &lt;a href="http://opensource.atlassian.com/projects/hibernate/browse/HV-307"&gt;planned&lt;/a&gt; to add support for the Joda types in an ucoming version of &lt;a href="http://www.hibernate.org/subprojects/validator.html"&gt;Hibernate Validator&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-5974115482043732340?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/tMWp5qB-O7s" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/tMWp5qB-O7s/providing-bean-validation-support-for.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>1</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/05/providing-bean-validation-support-for.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-1375446969561842488</guid><pubDate>Fri, 09 Apr 2010 19:52:00 +0000</pubDate><atom:updated>2010-04-11T21:25:42.108+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">JPA 2</category><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">JSR 303</category><category domain="http://www.blogger.com/atom/ns#">Bean Validation</category><title>Slides from JUG presentation on Bean Validation API available</title><description>&lt;p&gt;Recently I gave a presentation on &lt;a href="" title="http://jcp.org/en/jsr/detail?id=303"&gt;JSR 303&lt;/a&gt; ("Bean Validation") at the &lt;a href="http://www.jughh.org/"&gt;Java User Group&lt;/a&gt; in Hamburg, Germany.&lt;/p&gt;

&lt;p&gt;I did also some live coding during the talk and mentioned some things only verbally. Nevertheless I thought the slides (which are in German) might be of interest, so I decided to put them online.&lt;/p&gt;

&lt;div id="__ss_3677549" style="width:425px; margin: 0 auto"&gt;
&lt;object height="355" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=vortragbeanvalidationapi-100409141506-phpapp01&amp;stripped_title=objektvalidierung-mit-dem-bean-validation-api" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;embed allowfullscreen="true" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=vortragbeanvalidationapi-100409141506-phpapp01&amp;stripped_title=objektvalidierung-mit-dem-bean-validation-api" allowscriptaccess="always" type="application/x-shockwave-flash" height="355" width="425"&gt;&lt;/embed&gt;
&lt;/object&gt;
&lt;/div&gt;

&lt;p&gt;You can also find the presentation at &lt;a href="http://www.slideshare.net/gunnarmorling/objektvalidierung-mit-dem-bean-validation-api"&gt;slideshare&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The talk went pretty well, there were many questions and people generally seemed quite interested :-) One question related to the automatic validation of constraints at &lt;a href="http://jcp.org/en/jsr/detail?id=317"&gt;JPA&lt;/a&gt; entities I couldn't answer immediately, though. &lt;/p&gt;

&lt;p&gt;The question was, whether lazy properties are loaded from the database during validation of class-level constraints (for constraint validation at fields/properties lazy attributes must not be loaded, which is ensured by checking each attribute's load state using a &lt;a href="http://java.sun.com/javaee/6/docs/api/javax/validation/TraversableResolver.html"&gt;TraversableResolver&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Actually this can happen, depending on the attributes accessed by the validator implementation for the class-level constraint. I think, generally this is alright, as the validator needs to know the values of all attributes relevant for the evaluation of the constraint. If in certain scenarios this behavior is not acceptable, one could examine the attributes' load states manually using &lt;a href="http://java.sun.com/javaee/6/docs/api/javax/persistence/PersistenceUtil.html#isLoaded(java.lang.Object,%20java.lang.String)"&gt;javax.validation.PersistenceUtil&lt;/a&gt; and depending on that access only certain attributes.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-1375446969561842488?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/_9IZgVcDPvY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/_9IZgVcDPvY/slides-from-jug-presentation-on-bean.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>0</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/04/slides-from-jug-presentation-on-bean.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-8002817595273844572</guid><pubDate>Wed, 24 Mar 2010 23:22:00 +0000</pubDate><atom:updated>2010-03-25T00:24:13.421+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">JSR 303</category><category domain="http://www.blogger.com/atom/ns#">Bean Validation</category><title>Latest Bean Validation Links</title><description>&lt;p&gt;When I &lt;a href="http://musingsofaprogrammingaddict.blogspot.com/2009/01/getting-started-with-jsr-303-beans.html"&gt;started&lt;/a&gt; blogging on &lt;a href="http://jcp.org/en/jsr/detail?id=303"&gt;JSR 303&lt;/a&gt; ("Bean Validation"), there was not too much information available on the web concerning the BV API, its usage and its integration with other technologies.&lt;/p&gt;

&lt;p&gt;In between JSR 303 got approved, BV is part of &lt;a href="http://jcp.org/en/jsr/detail?id=316"&gt;Java EE 6&lt;/a&gt; and as it generally gains wider adoption, more and more blog posts and other information related to Bean Validation come available.&lt;/p&gt;

&lt;p&gt;That's why I thought it might be a good idea to collect the most interesting pieces and publish those links here every once in a while.&lt;/p&gt;

&lt;p&gt;And there you go, here is the first couple of links related to JSR 303:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://community.jboss.org/docs/DOC-15041"&gt; How to write a custom ConstraintValidatorFactory&lt;/a&gt; (Hardy Ferentschik, March 23rd, 2010)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://agoncal.wordpress.com/2010/03/03/bean-validation-with-jpa-1-0/"&gt;Bean Validation with JPA 1.0&lt;/a&gt; (Antonio Goncalves, March 3rd, 2010)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.smart-java.nl/blog/index.php/2010/03/17/jsf-2-0-clientbehavior-bean-validation-in-javascript/"&gt;JSF 2.0 ClientBehavior: Bean Validation in JavaScript&lt;/a&gt; (Jan-Kees van Andel, March 17th, 2010)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.smart-java.nl/blog/index.php/2010/03/12/unit-testing-a-bean-validation-constraintvalidator/"&gt;Unit Testing a Bean Validation ConstraintValidator&lt;/a&gt; (Jan-Kees van Andel, March 12th, 2010)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.inflinx.com/2010/03/10/jsr-303-bean-validation-using-spring-3/"&gt;JSR 303 Bean Validation Using Spring 3&lt;/a&gt; (Balaji, March 10th, 2010)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.zenika.com/index.php?post/2010/02/24/Wicket-JSR-303-Validators"&gt;Wicket JSR-303 Validators&lt;/a&gt; (Ophelie Salm, February 25rd, 2010)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I plan to post follow-ups, whenever I gathered some interesting links, so stay tuned.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-8002817595273844572?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/ZCWaCLma6Is" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/ZCWaCLma6Is/latest-bean-validation-links.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>1</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/03/latest-bean-validation-links.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-3731935365956116091</guid><pubDate>Tue, 16 Mar 2010 21:04:00 +0000</pubDate><atom:updated>2010-03-16T22:06:16.786+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">IntelliJ IDEA</category><category domain="http://www.blogger.com/atom/ns#">Java</category><title>Import code style settings into IntelliJ IDEA</title><description>&lt;p&gt;Recently I received an &lt;a href="http://www.jetbrains.com/idea/"&gt;IntelliJ IDEA&lt;/a&gt; code style settings file for &lt;a href="https://www.hibernate.org/412.html"&gt;Hibernate Validator&lt;/a&gt;, the reference implementation of &lt;a href="http://jcp.org/en/jsr/detail?id=303"&gt;JSR 303&lt;/a&gt; ("Bean Validation"), to which I'm contributing.&lt;/p&gt;

&lt;p&gt;I wanted to import it into IntelliJ in order to format any code changes I make in the project's standard style. But as it turned out, there is no functionality within the IDE for importing code style settings. Instead one has to do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy the settings XML file to INTELLIJ_SETTINGS_DIR/config/codestyles (where INTELLIJ_SETTINGS_DIR is the folder containing your IntelliJ settings; typically it is situated within your home directory, the name depends on your version of IntelliJ; in my case the complete path is "~/.IdeaIC90/config/codestyles")&lt;/li&gt;
&lt;li&gt;Start IntelliJ&lt;/li&gt;
&lt;li&gt;Go to "File" - "Settings" - "Code Style", select "Use global settings" and choose the previously imported style from the drop-down box&lt;/li&gt;
&lt;li&gt;Optionally apply the style to one project only by clicking on "Copy to Project" and selecting "Use per project settings" afterwards&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-3731935365956116091?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/xn8nt7ck3Bg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/xn8nt7ck3Bg/import-code-style-settings-into.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>2</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/03/import-code-style-settings-into.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-7057030505874317153</guid><pubDate>Tue, 09 Mar 2010 14:01:00 +0000</pubDate><atom:updated>2010-03-10T12:00:59.439+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Metro</category><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">JAX-WS</category><category domain="http://www.blogger.com/atom/ns#">web services</category><category domain="http://www.blogger.com/atom/ns#">JMX</category><title>Runtime Configuration of Schema Validation using Metro</title><description>&lt;p&gt;When working with XML-based web services, it usually a good idea to validate all requests and responses against their associated &lt;a href="http://www.w3.org/XML/Schema"&gt;XML schema&lt;/a&gt; in order to ensure the integrity of the incoming/outgoing messages.&lt;/p&gt;

&lt;p&gt;Unfortunately &lt;a href="http://jcp.org/en/jsr/detail?id=224"&gt;JAX-WS&lt;/a&gt;, the standard API for SOAP-based web services of the Java Platform doesn't specify a standard way for schema validation. Therefore most of the JAX-WS implementations such as &lt;a href="https://metro.dev.java.net/"&gt;Metro&lt;/a&gt; or &lt;a href="http://cxf.apache.org/"&gt;CXF&lt;/a&gt; provide a proprietary mechanism to perform that task.&lt;/p&gt;

&lt;p&gt;Using Metro, this is simply done by annotating the endpoint class with &lt;a href="https://jax-ws.dev.java.net/guide/Schema_Validation.html"&gt;@SchemaValidation&lt;/a&gt;:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@WebService&lt;/span&gt;(endpointInterface = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;...&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@SchemaValidation&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;VideoRentalPort&lt;/span&gt; &lt;span class="di"&gt;implements&lt;/span&gt; VideoRentalPortType {&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;//...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;This works as expected, but has one big flaw in my eyes: to enable or disable validation for a given endpoint, the application code must be modified, followed by a re-deployment of the application.&lt;/p&gt;

&lt;p&gt;This is not viable in many scenarios. Taking a large enterprise application with a whole lot of services for example, schema validation might be turned off by default for performance reasons. But for the purpose of bug analysis it might be required to temporarily enable validation for single endpoints. Re-deploying the application is not an option in this scenario.&lt;/p&gt;

&lt;p&gt;That's why I had a look into Metro's implementation of the validation feature and tried to find a way to make schema validation configurable during runtime.&lt;/p&gt;

&lt;h2&gt;Custom Metro tubes&lt;/h2&gt;

&lt;p&gt;Schema validation in Metro is realized using in form of a so-called "tube". Metro tubes are conceptually similar to JAX-WS message handlers, but a magnitude more powerful. Since Metro 2.0 the tubes to be applied for a given application can be configured by providing so-called &lt;a href="http://wikis.glassfish.org/metro/Wiki.jsp?page=DeclarativeTubelineAssemblerOnePager"&gt;custom "tubelines"&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So the basic idea is to extend the standard validation tube provided by Metro in a way which makes it runtime-configurable and register this customized tube instead of the original one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Before going into details, it should be said that as of Metro 2.0 the tube-related APIs &lt;a href="http://marek.potociar.net/2009/10/19/custom-metro-tube-interceptor/"&gt;are regarded&lt;/a&gt; as Metro-internal APIs, so they could be changed in future versions, causing the approach described here not to work anymore. But as we don't write very much code, this shouldn't really scare us.&lt;/p&gt;

&lt;h2&gt;Managing configuration state&lt;/h2&gt;

&lt;p&gt;First of all, some sort of data structure is needed, which will store whether validation is enabled for a given web service endpoint. For this purpose a simple map is sufficient (as this class must be accessible for multiple threads at the same time, a &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/ConcurrentMap.html"&gt;ConcurrentMap&lt;/a&gt; is used):&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;ValidationConfigurationHolder&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;ConcurrentMap&lt;/span&gt;&amp;lt;&lt;span class="ty"&gt;String&lt;/span&gt;, &lt;span class="ty"&gt;Boolean&lt;/span&gt;&amp;gt; configuration = &lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;ConcurrentHashMap&lt;/span&gt;&amp;lt;&lt;span class="ty"&gt;String&lt;/span&gt;, &lt;span class="ty"&gt;Boolean&lt;/span&gt;&amp;gt;();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;boolean&lt;/span&gt; isValidationEnabled(&lt;span class="ty"&gt;String&lt;/span&gt; portName) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ty"&gt;Boolean&lt;/span&gt; theValue = configuration.get(portName);&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; theValue != &lt;span class="kw"&gt;null&lt;/span&gt; ? theValue : &lt;span class="ty"&gt;Boolean&lt;/span&gt;.TRUE;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; setValidationEnabled(&lt;span class="ty"&gt;String&lt;/span&gt; portName, &lt;span class="ty"&gt;boolean&lt;/span&gt; enabled) {&lt;tt&gt;
&lt;/tt&gt;        configuration.put(portName, enabled);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Next we need a way to manipulate this structure during application runtime. Java's standard API for management purposes as the one at hand is &lt;a href="http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/"&gt;JMX&lt;/a&gt;. The following listing shows a JMX MBean, which later can be invoked to enable or disable validation for a given port:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="c"&gt;//MBean interface&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;interface&lt;/span&gt; EndpointConfigurationMBean {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; getName();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;boolean&lt;/span&gt; isSchemaValidationEnabled();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; setSchemaValidationEnabled(&lt;span class="ty"&gt;boolean&lt;/span&gt; enabled);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;//MBean implementation&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;EndpointConfiguration&lt;/span&gt; &lt;span class="di"&gt;implements&lt;/span&gt; EndpointConfigurationMBean {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; name;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; EndpointConfiguration() {}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; EndpointConfiguration(&lt;span class="ty"&gt;String&lt;/span&gt; name) {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.name = name;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; getName() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; name;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;boolean&lt;/span&gt; isSchemaValidationEnabled() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; ValidationConfigurationHolder.isValidationEnabled(name);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; setSchemaValidationEnabled(&lt;span class="ty"&gt;boolean&lt;/span&gt; enabled) {&lt;tt&gt;
&lt;/tt&gt;        ValidationConfigurationHolder.setValidationEnabled(name, enabled);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;h2&gt;The customized validation tube&lt;/h2&gt;

&lt;p&gt;The schema validation support of Metro is basically realized in three classes: &lt;a href="http://fisheye5.cenqua.com/browse/jax-ws-sources/jaxws-ri/rt/src/com/sun/xml/ws/util/pipe/AbstractSchemaValidationTube.java"&gt;AbstractSchemaValidationTube&lt;/a&gt; and &lt;a href="http://fisheye5.cenqua.com/browse/jax-ws-sources/jaxws-ri/rt/src/com/sun/xml/ws/server/ServerSchemaValidationTube.java"&gt;ServerSchemaValidationTube&lt;/a&gt; resp. &lt;a href="http://fisheye5.cenqua.com/browse/jax-ws-sources/jaxws-ri/rt/src/com/sun/xml/ws/client/ClientSchemaValidationTube.java"&gt;ClientSchemaValidationTube&lt;/a&gt; which extend the former. To make schema validation configurable on the server side, we create a sub-class of ServerSchemaValidationTube:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;ConfigurableServerSchemaValidationTube&lt;/span&gt; &lt;span class="di"&gt;extends&lt;/span&gt; ServerSchemaValidationTube {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; name;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; ConfigurableServerSchemaValidationTube(WSEndpoint&amp;lt;?&amp;gt; endpoint, WSBinding binding,&lt;tt&gt;
&lt;/tt&gt;            SEIModel seiModel, WSDLPort wsdlPort, Tube next) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;super&lt;/span&gt;(endpoint, binding, seiModel, wsdlPort, next);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        name = seiModel.getServiceQName().getLocalPart() + &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + wsdlPort.getName().getLocalPart();&lt;tt&gt;
&lt;/tt&gt;        ValidationConfigurationHolder.setValidationEnabled(name, &lt;span class="kw"&gt;true&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        registerMBean();&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; registerMBean() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ty"&gt;MBeanServer&lt;/span&gt; mbs = &lt;span class="ty"&gt;ManagementFactory&lt;/span&gt;.getPlatformMBeanServer(); &lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;try&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;            mbs.registerMBean(&lt;tt&gt;
&lt;/tt&gt;                &lt;span class="kw"&gt;new&lt;/span&gt; EndpointConfiguration(name),&lt;tt&gt;
&lt;/tt&gt;                &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;ObjectName&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;de.gmorling.moapa.videorental.jmx:type=Endpoints,name=&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + name));&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;catch&lt;/span&gt; (&lt;span class="ty"&gt;Exception&lt;/span&gt; e) {&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;throw&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;RuntimeException&lt;/span&gt;(e);&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;protected&lt;/span&gt; &lt;span class="ty"&gt;boolean&lt;/span&gt; isNoValidation() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; !ValidationConfigurationHolder.isValidationEnabled(name);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;protected&lt;/span&gt; ConfigurableServerSchemaValidationTube(ConfigurableServerSchemaValidationTube that, TubeCloner cloner) {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;super&lt;/span&gt;(that,cloner);&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.name = that.name;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; ConfigurableServerSchemaValidationTube copy(TubeCloner cloner) {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; ConfigurableServerSchemaValidationTube(&lt;span class="lv"&gt;this&lt;/span&gt;, cloner);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;The important thing here is, that the method isNoValidation() is overridden. This method is defined within the base class AbstractSchemaValidationTube and is invoked whenever a request/response is processed by this tube. The implementation of this method simply delegates to the ValidationConfigurationHolder shown above.&lt;/p&gt;

&lt;p&gt;Within the constructor an instance of the EndpointConfiguration MBean for the given endpoint is registered with the platform MBean server, which later can be used to toggle validation for this endpoint.&lt;/p&gt;

&lt;h2&gt;Providing a TubeFactory&lt;/h2&gt;

&lt;p&gt;Metro tubes are instantiated by implementations of the &lt;a href="http://fisheye5.cenqua.com/browse/wsit/wsit/rt/src/com/sun/xml/ws/assembler/TubeFactory.java"&gt;TubeFactory&lt;/a&gt; interface. The following implementation allows the Metro runtime to retrieve instances of the ConfigurableServerSchemaValidationTube:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;ConfigurableValidationTubeFactory&lt;/span&gt; &lt;span class="di"&gt;implements&lt;/span&gt; TubeFactory {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;//...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; Tube createTube(ServerTubelineAssemblyContext context)&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="di"&gt;throws&lt;/span&gt; WebServiceException {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        ServerTubeAssemblerContext wrappedContext = context.getWrappedContext();&lt;tt&gt;
&lt;/tt&gt;        WSEndpoint&amp;lt;?&amp;gt; endpoint = wrappedContext.getEndpoint();&lt;tt&gt;
&lt;/tt&gt;        WSBinding binding = endpoint.getBinding();&lt;tt&gt;
&lt;/tt&gt;        Tube next = context.getTubelineHead();&lt;tt&gt;
&lt;/tt&gt;        WSDLPort wsdlModel = wrappedContext.getWsdlModel();&lt;tt&gt;
&lt;/tt&gt;        SEIModel seiModel = wrappedContext.getSEIModel();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (binding &lt;span class="kw"&gt;instanceof&lt;/span&gt; SOAPBinding &amp;amp;&amp;amp; binding.isFeatureEnabled(SchemaValidationFeature.class) &amp;amp;&amp;amp; wsdlModel != &lt;span class="kw"&gt;null&lt;/span&gt;) {&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; ConfigurableServerSchemaValidationTube(endpoint, binding, seiModel, wsdlModel, next);&lt;tt&gt;
&lt;/tt&gt;        } &lt;span class="kw"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;return&lt;/span&gt; next;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;The code resembles Metro's instantiation logic for the standard validation tube, the only difference being that a ConfigurableServerSchemaValidationTube is created. Note that we also check whether the SchemaValidationFeature is enabled or not. That way given endpoints can be completey excluded from validation by simply not annotating them with @SchemaValidation.&lt;/p&gt;

&lt;p&gt;To register the tube factory with Metro as part of a custom tubeline the configuration file META-INF/metro.xml has to be provided:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="pp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;metro&lt;/span&gt;  &lt;span class="an"&gt;xmlns:xsi&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;   &lt;span class="an"&gt;xmlns&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;http://java.sun.com/xml/ns/metro/config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;   &lt;span class="an"&gt;version&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;1.0&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;tubelines&lt;/span&gt; &lt;span class="an"&gt;default&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;#custom-tubeline&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ta"&gt;&amp;lt;tubeline&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;custom-tubeline&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;client-side&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;                ...&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;/client-side&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;endpoint-side&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;                ...&lt;tt&gt;
&lt;/tt&gt;                &lt;span class="ta"&gt;&amp;lt;tube-factory&lt;/span&gt; &lt;span class="an"&gt;className&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;com.sun.xml.ws.assembler.jaxws.HandlerTubeFactory&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;                &lt;span class="ta"&gt;&amp;lt;tube-factory&lt;/span&gt; &lt;span class="an"&gt;className&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;de.gmorling.moapa.videorental.metro.ConfigurableValidationTubeFactory&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;                &lt;span class="ta"&gt;&amp;lt;tube-factory&lt;/span&gt; &lt;span class="an"&gt;className&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;com.sun.xml.ws.assembler.jaxws.TerminalTubeFactory&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;/endpoint-side&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ta"&gt;&amp;lt;/tubeline&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;/tubelines&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/metro&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;As suggested in a &lt;a href="http://marek.potociar.net/2009/10/19/custom-metro-tube-interceptor/"&gt;post&lt;/a&gt; by Metro developer Marek Potociar it's a good idea to take Metro's standard tube configuration, metro-default.xml, as template and adapt it as needed. In our case the ConfigurableValidationTubeFactory is registered instead of the standard ValidationTubeFactory.&lt;/p&gt;

&lt;h2&gt;Configuring Schema Validation using VisualVM&lt;/h2&gt;

&lt;p&gt;Having registered the tube factory, it's time to give the whole thing a test run. A complete project containing all sources of this post together with an examplary video rental web service can be found in my Git &lt;a href="http://github.com/gunnarmorling/musings-of-a-programming-addict/tree/master/configurable-schema-validation/"&gt;repo&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;When starting the project's main class the service will be fired up and waiting for requests. Any JMX client such as &lt;a href="https://visualvm.dev.java.net/"&gt;VisualVM&lt;/a&gt; can now be used to connect to the running JVM. The following screenshot shows VisualVM connected to the video rental application:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://4.bp.blogspot.com/_Ams_WxvNvnk/S5ZU2QfmswI/AAAAAAAAAA8/iXq-jLBE7ec/s1600-h/2010_03_09_visual_vm.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img src="http://4.bp.blogspot.com/_Ams_WxvNvnk/S5ZU2QfmswI/AAAAAAAAAA8/iXq-jLBE7ec/s400/2010_03_09_visual_vm.png" border="0" id="BLOGGER_PHOTO_ID_5446634090468389634" alt="" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 245px;" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By setting the value of the "SchemaValidationEnabled" property of the MBean named "VideoRentalService-VideoRentalPort", schema validation now can be enabled or disabled for the corresponding endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update (march 10, 2010):&lt;/strong&gt; I created an request for enhancement for that feature: &lt;a href="https://jax-ws.dev.java.net/issues/show_bug.cgi?id=839"&gt;Allow schema validation to be enabled/disabled at runtime&lt;/a&gt;. So let's see, whether this will be part of some future Metro version :-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-7057030505874317153?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/eouefE3dWfk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/eouefE3dWfk/runtime-configuration-of-schema.html</link><author>noreply@blogger.com (Gunnar Morling)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_Ams_WxvNvnk/S5ZU2QfmswI/AAAAAAAAAA8/iXq-jLBE7ec/s72-c/2010_03_09_visual_vm.png" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/03/runtime-configuration-of-schema.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-7921484800218695599</guid><pubDate>Mon, 15 Feb 2010 23:41:00 +0000</pubDate><atom:updated>2010-02-19T21:10:31.509+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">JSR 303</category><category domain="http://www.blogger.com/atom/ns#">Bean Validation</category><title>A generic class-level constraint for the Bean Validation API</title><description>&lt;p&gt;One question I'm being asked pretty often when talking about the Bean Validation API (&lt;a href="http://jcp.org/en/jsr/detail?id=303"&gt;JSR 303&lt;/a&gt;) is, how cross-field validation can be done. The canonical example for this is a class representing a calendar event, where the end date of an event shall always be later than the start date.&lt;/p&gt;

&lt;p&gt;This and other scenarios where validation depends on the values of multiple attributes of a given object can be realized by implementing a &lt;a href="http://docs.jboss.org/hibernate/stable/validator/reference/en/html_single/#d0e328"&gt;class-level constraint&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That basically works pretty well, nevertheless this is one part of the BV spec, I'm not too comfortable with. This is mainly for two reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You'll probably need a dedicated constraint for every reasonably complex business object. Providing an annotation, a validator implementation and an error message for each can become pretty tedious.&lt;/li&gt;
&lt;li&gt;Business objects typically know best themselves, whether they are in a consistent, valid state or not. By putting validation logic into a separate constraint validator class, objects have to expose their internal state, which otherwise might not be required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To circumvent these problems, &lt;a href="(http://musingsofaprogrammingaddict.blogspot.com/2009/08/script-annotation-for-bean-validation.html"&gt;I suggested&lt;/a&gt; a while ago a generic constraint annotation, which allows the use of script expressions written in languages such as &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt; to implement validation logic directly at the validated class.&lt;/p&gt;

&lt;p&gt;This approach frees you from the need to implement dedicated constraints for each relevant business object, but also comes at the cost of losing type-safety at compile-time.&lt;/p&gt;

&lt;p&gt;The constraint presented in the following therefore tries to combine genericity with compile-time type safety. The basic idea is to implement validation logic within the business objects themselves and to invoke this logic from within a generic constraint class. &lt;/p&gt;

&lt;p&gt;In order to do so let's first define an interface to be implemented by any validatable class:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;interface&lt;/span&gt; Validatable {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;boolean&lt;/span&gt; isValid();&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Next we define a constraint annotation, @SelfValidating, which we'll use later on to annotate Validatable implementations:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@Target&lt;/span&gt;( { TYPE })&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@Retention&lt;/span&gt;(RUNTIME)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@Constraint&lt;/span&gt;(validatedBy = SelfValidatingValidator.class)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@Documented&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="at"&gt;@interface&lt;/span&gt; SelfValidating {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ty"&gt;String&lt;/span&gt; message() &lt;span class="kw"&gt;default&lt;/span&gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;{de.gmorling.moapa.self_validating.SelfValidating.message}&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ty"&gt;Class&lt;/span&gt;&amp;lt;?&amp;gt;&lt;span class="ty"&gt;[]&lt;/span&gt; groups() &lt;span class="kw"&gt;default&lt;/span&gt; {};&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ty"&gt;Class&lt;/span&gt;&amp;lt;? &lt;span class="di"&gt;extends&lt;/span&gt; Payload&amp;gt;&lt;span class="ty"&gt;[]&lt;/span&gt; payload() &lt;span class="kw"&gt;default&lt;/span&gt; {};&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Of course we also need a constraint validator implementation, which is able to evaluate that constraint:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;SelfValidatingValidator&lt;/span&gt; &lt;span class="di"&gt;implements&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    ConstraintValidator&amp;lt;SelfValidating, Validatable&amp;gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; initialize(SelfValidating constraintAnnotation) {}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;boolean&lt;/span&gt; isValid(Validatable value,&lt;tt&gt;
&lt;/tt&gt;        ConstraintValidatorContext constraintValidatorContext) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; value.isValid();&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;The implementation is trivial, as nothing is to do in initialize() and the isValid() method just delegates the call to the validatable object itself.&lt;/p&gt;

&lt;p&gt;Finally we need a properties file named ValidationMessages.properties containing the default error message for the constraint:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;de.gmorling.moapa.self_validating.SelfValidating.message=Validatable object couldn't be validated successfully.&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Taking the calendar event example from the beginning, usage of the constraint might look as follows:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@SelfValidating&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;CalendarEvent&lt;/span&gt; &lt;span class="di"&gt;implements&lt;/span&gt; Validatable {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@NotNull&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;final&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; title;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;final&lt;/span&gt; &lt;span class="ty"&gt;Date&lt;/span&gt; startDate;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;final&lt;/span&gt; &lt;span class="ty"&gt;Date&lt;/span&gt; endDate;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; CalendarEvent(&lt;span class="ty"&gt;String&lt;/span&gt; title, &lt;span class="ty"&gt;Date&lt;/span&gt; startDate, &lt;span class="ty"&gt;Date&lt;/span&gt; endDate) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.title = title;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.startDate = startDate;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.endDate = endDate;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;boolean&lt;/span&gt; isValid() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; startDate == &lt;span class="kw"&gt;null&lt;/span&gt; || endDate == &lt;span class="kw"&gt;null&lt;/span&gt; || startDate.before(endDate);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; toString() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ty"&gt;DateFormat&lt;/span&gt; format = &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;SimpleDateFormat&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;dd.MM.yyyy&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;tt&gt;
&lt;/tt&gt;            title + &lt;tt&gt;
&lt;/tt&gt;            &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt; from &lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; +  (startDate == &lt;span class="kw"&gt;null&lt;/span&gt; ? &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; : format.format(startDate)) + &lt;tt&gt;
&lt;/tt&gt;            &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt; till &lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + (endDate == &lt;span class="kw"&gt;null&lt;/span&gt; ? &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; : format.format(endDate));&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;A short unit test shows that the constraint works as expected:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;SelfValidatingTest&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;Validator&lt;/span&gt; validator;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;Date&lt;/span&gt; startDate;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;Date&lt;/span&gt; endDate;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@BeforeClass&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; setUpValidatorAndDates() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();&lt;tt&gt;
&lt;/tt&gt;        validator = validatorFactory.getValidator();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        startDate = &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;GregorianCalendar&lt;/span&gt;(&lt;span class="i"&gt;2009&lt;/span&gt;, &lt;span class="i"&gt;8&lt;/span&gt;, &lt;span class="i"&gt;20&lt;/span&gt;).getTime();&lt;tt&gt;
&lt;/tt&gt;        endDate = &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;GregorianCalendar&lt;/span&gt;(&lt;span class="i"&gt;2009&lt;/span&gt;, &lt;span class="i"&gt;8&lt;/span&gt;, &lt;span class="i"&gt;21&lt;/span&gt;).getTime();&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Test&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; calendarEventIsValidAsEndDateIsAfterStartDate() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        CalendarEvent testEvent = &lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;new&lt;/span&gt; CalendarEvent(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Team meeting&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, startDate, endDate);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        assertTrue(validator.validate(testEvent).isEmpty());&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Test&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; calendarEventIsInvalidAsEndDateIsBeforeStartDate() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        CalendarEvent testEvent = &lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;new&lt;/span&gt; CalendarEvent(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Team meeting&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, endDate, startDate);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ty"&gt;Set&lt;/span&gt;&amp;lt;ConstraintViolation&amp;lt;CalendarEvent&amp;gt;&amp;gt; constraintViolations = &lt;tt&gt;
&lt;/tt&gt;            validator.validate(testEvent);&lt;tt&gt;
&lt;/tt&gt;        assertEquals(&lt;span class="i"&gt;1&lt;/span&gt;, constraintViolations.size());&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        assertEquals(&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Object couldn't be validated successfully.&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;            constraintViolations.iterator().next().getMessage());&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;This works like a charm, only the error message returned by the BV runtime is not yet very expressive. This can easily be solved, as the BV API allows to override error messages within constraint annotations:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@SelfValidating&lt;/span&gt;(message=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;{de.gmorling.moapa.self_validating.CalendarEvent.message}&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;CalendarEvent&lt;/span&gt; &lt;span class="di"&gt;implements&lt;/span&gt; Validatable {&lt;tt&gt;
&lt;/tt&gt;    ...&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Again we need an entry in ValidationMessages.properties for the specified message key:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;de.gmorling.moapa.self_validating.CalendarEvent.message=End date of event must be after start date.&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Providing dedicated class-level constraints for all business objects that require some sort of cross-field validation logic can be quite a tedious task as you need to create an annotation type, a validator implementation and an error message text.&lt;/p&gt;

&lt;p&gt;The @SelfValidating constraint reduces the required work by letting business objects validate themselves. That way all you have to do is implement the Validatable interface, annotate your class with @SelfValidating and optionally provide a customized error message. Furthermore business objects are not required to expose their internal state to make it accessible for an external validator implementation.&lt;/p&gt;

&lt;p&gt;The complete source code can be found in my GitHub &lt;a href="http://github.com/gunnarmorling/musings-of-a-programming-addict/tree/master/self-validating/"&gt;repository&lt;/a&gt;. As always I'd be happy about any feedback.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-7921484800218695599?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/XZXpgXefFws" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/XZXpgXefFws/generic-class-level-constraint-for-bean.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>6</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/02/generic-class-level-constraint-for-bean.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-5073159143288658535</guid><pubDate>Sat, 06 Feb 2010 12:01:00 +0000</pubDate><atom:updated>2010-02-06T13:04:05.260+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">contract-first</category><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">JAXB</category><category domain="http://www.blogger.com/atom/ns#">JAX-WS</category><category domain="http://www.blogger.com/atom/ns#">XmlBeans</category><category domain="http://www.blogger.com/atom/ns#">web services</category><title>Integrating JAX-WS with XmlBeans</title><description>&lt;p&gt;&lt;a href="http://jcp.org/en/jsr/detail?id=224"&gt;JAX-WS&lt;/a&gt; as Java's standard API for web services comes with a close integration of &lt;a href="http://jcp.org/en/jsr/detail?id=222"&gt;JAXB&lt;/a&gt; as XML binding framework. More precisely JAXB is actually the only binding technology directly supported by JAX-WS. As JAXB basically does its job pretty well, that's nothing bad per se.&lt;/p&gt;

&lt;p&gt;Nevertheless there might be situations where you would like to integrate JAX-WS with other XML binding solutions such as Apache &lt;a href="http://xmlbeans.apache.org/"&gt;XmlBeans&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;For instance you might have used another web service stack and binding framework in the past and now want to migrate your services to JAX-WS. Depending on the number of services, changing your XML binding framework can create quite a lot of work, as you have to rewrite the mapping code which converts between the types generated by the binding framework and your domain objects. &lt;/p&gt;

&lt;h2&gt;Provider-based endpoints&lt;/h2&gt;

&lt;p&gt;The key idea for integrating JAX-WS with another binding framework is to create a &lt;a href="http://java.sun.com/javaee/6/docs/api/javax/xml/ws/Provider.html"&gt;Provider&lt;/a&gt; based endpoint for your web service. Contrary to standard &lt;a href="http://java.sun.com/javaee/6/docs/api/javax/jws/WebService.html"&gt;SEI&lt;/a&gt; (service endpoint interface) implementations, which solely operate on JAXB generated classes, a provider endpoint has access to the raw XML of incoming and outgoing messages.&lt;/p&gt;

&lt;p&gt;That way you can take care of XML marshalling yourself, e.g. by converting incoming XML messages into their corresponding XmlBeans types and the other way around.&lt;/p&gt;

&lt;p&gt;In the following a web service for a video rental store shall be built. The service has a single operation, getMovieById, with request and response types in an accompanying XML schema (the service's WSDL and all other sources for this post can be found in my Git &lt;a href="http://github.com/gunnarmorling/musings-of-a-programming-addict/tree/master/jaxws-on-xmlbeans/"&gt;repository&lt;/a&gt;):&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="pp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;schema&lt;/span&gt; &lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;targetNamespace&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://www.gunnarmorling.de/moapa/videorental/types&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xmlns&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://www.w3.org/2001/XMLSchema&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xmlns:videorental&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://www.gunnarmorling.de/moapa/videorental/types&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;element&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;GetMovieByIdRequest&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;videorental:GetMovieByIdRequest&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;element&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;GetMovieByIdResponse&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;videorental:GetMovieByIdResponse&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;complexType&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;GetMovieByIdRequest&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ta"&gt;&amp;lt;sequence&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;element&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Id&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ta"&gt;&amp;lt;/sequence&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;/complexType&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;complexType&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;GetMovieByIdResponse&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ta"&gt;&amp;lt;sequence&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;element&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;videorental:Movie&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Movie&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;minOccurs&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ta"&gt;&amp;lt;/sequence&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;/complexType&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;complexType&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Movie&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ta"&gt;&amp;lt;sequence&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;element&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Id&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;element&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Title&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;element&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;RunTime&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;int&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ta"&gt;&amp;lt;/sequence&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;/complexType&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/schema&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;XmlBeans will generate two document types for the elements (GetMovieByIdRequestDocument, GetMovieByIdResponseDocument) as well as types for each of the complex types.&lt;/p&gt;

&lt;p&gt;For the service implementation I recommend to work only with the classes representing the complex types (instead of the document types). An interface representing the service's port type and its implementation therefore might look like this:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;interface&lt;/span&gt; VideoRentalPortType {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; GetMovieByIdResponse getMovieById(GetMovieByIdRequest request);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;public &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;VideoRentalPort&lt;/span&gt; &lt;span class="di"&gt;implements&lt;/span&gt; VideoRentalPortType {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; MovieRepository movieRepository = &lt;span class="kw"&gt;new&lt;/span&gt; MovieRepositoryMockImpl();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; GetMovieByIdResponse getMovieById(GetMovieByIdRequest request) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        GetMovieByIdResponse response = GetMovieByIdResponse.Factory.newInstance();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        de.gmorling.moapa.videorental.domain.Movie movie = movieRepository.getMovieById(request.getId());&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;if&lt;/span&gt;(movie != &lt;span class="kw"&gt;null&lt;/span&gt;) {&lt;tt&gt;
&lt;/tt&gt;            response.setMovie(convert(movie));&lt;tt&gt;
&lt;/tt&gt;        }       &lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; response;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; Movie convert(de.gmorling.moapa.videorental.domain.Movie movie) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        Movie theValue = Movie.Factory.newInstance();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        theValue.setId(movie.getId());&lt;tt&gt;
&lt;/tt&gt;        theValue.setTitle(movie.getTitle());&lt;tt&gt;
&lt;/tt&gt;        theValue.setRunTime(movie.getRunTime());&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; theValue;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;This looks pretty similar to a typical SEI-based implementation. The only difference is, that the types in use are generated by XmlBeans instead of JAXB. The implementation is straight forward. It takes the movie id from the incoming request, invokes some backend business service and creates a GetMovieByIdResponse from the result.&lt;/p&gt;

&lt;p&gt;Next we need to create the actual Provider implementation which will be called by the JAX-WS runtime, whenever the service is invoked:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@WebServiceProvider&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@ServiceMode&lt;/span&gt;(value=Mode.MESSAGE)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;VideoRentalProvider&lt;/span&gt; &lt;span class="di"&gt;implements&lt;/span&gt; &lt;span class="ty"&gt;Provider&lt;/span&gt;&amp;lt;SOAPMessage&amp;gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; VideoRentalPortType videoRentalPort = &lt;span class="kw"&gt;new&lt;/span&gt; VideoRentalPort();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; SOAPMessage invoke(SOAPMessage request) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;try&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;            Node root = request.getSOAPBody().getFirstChild();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;if&lt;/span&gt;(root.getNodeName().contains(GetMovieByIdRequest.class.getSimpleName())) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;                GetMovieByIdRequestDocument requestDocument = GetMovieByIdRequestDocument.Factory.parse(root);&lt;tt&gt;
&lt;/tt&gt;                GetMovieByIdResponseDocument responseDocument = GetMovieByIdResponseDocument.Factory.newInstance();&lt;tt&gt;
&lt;/tt&gt;                responseDocument.setGetMovieByIdResponse(videoRentalPort.getMovieById(requestDocument.getGetMovieByIdRequest()));&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;                &lt;span class="kw"&gt;return&lt;/span&gt; createSOAPMessage(responseDocument);&lt;tt&gt;
&lt;/tt&gt;            }&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;else&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;                &lt;span class="kw"&gt;throw&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;UnsupportedOperationException&lt;/span&gt;();&lt;tt&gt;
&lt;/tt&gt;            }&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;catch&lt;/span&gt;(&lt;span class="ty"&gt;Exception&lt;/span&gt; e) {&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;throw&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;RuntimeException&lt;/span&gt;(e);&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; SOAPMessage createSOAPMessage(XmlObject responseDocument) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;try&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;            SOAPMessage message = MessageFactory.newInstance().createMessage();&lt;tt&gt;
&lt;/tt&gt;            Node node = message.getSOAPBody().getOwnerDocument().importNode(responseDocument.getDomNode().getFirstChild(), &lt;span class="kw"&gt;true&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;            message.getSOAPBody().appendChild(node);&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;return&lt;/span&gt; message;&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;catch&lt;/span&gt;(&lt;span class="ty"&gt;Exception&lt;/span&gt; e) {&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;throw&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;RuntimeException&lt;/span&gt;(e);&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;A provider implementation must be annotated with &lt;a href="http://java.sun.com/javaee/6/docs/api/javax/xml/ws/WebServiceProvider.html"&gt;@WebServiceProvider&lt;/a&gt;. By binding the type parameter to &lt;a href="http://java.sun.com/javaee/6/docs/api/javax/xml/soap/SOAPMessage.html"&gt;SOAPMessage&lt;/a&gt; (a comparison with the alternatives &lt;a href="http://java.sun.com/javase/6/docs/api/javax/xml/transform/Source.html"&gt;Source&lt;/a&gt; and &lt;a href="http://java.sun.com/javase/6/docs/api/javax/activation/DataSource.html"&gt;DataSource&lt;/a&gt; can be found &lt;a href="http://weblogs.java.net/blog/2006/03/20/jax-ws-20-provider-based-endpoints-explained"&gt;here&lt;/a&gt;) and specifying &lt;a href="http://java.sun.com/javaee/6/docs/api/javax/xml/ws/Service.Mode.html#MESSAGE"&gt;Mode.MESSAGE&lt;/a&gt; within the &lt;a href="http://java.sun.com/javaee/6/docs/api/javax/xml/ws/ServiceMode.html"&gt;@ServiceMode&lt;/a&gt; annotation we achieve, that we can access complete SOAP messages within the implementation.&lt;/p&gt;

&lt;p&gt;The Provider interface defines only one method, invoke(). This method is called whenever any of the service's operations is invoked. Therefore we first have to determine the currently invoked operation, which can be done by peeking at the node name of the first body element. &lt;/p&gt;

&lt;p&gt;In case of the getMovieById operation then a GetMovieByIdRequestDocument instance representing the contents of the message body is created using a XmlBeans-generated factory class. From that document we retrieve the actual request element and pass it to the port implementation.&lt;/p&gt;

&lt;p&gt;The result is put into a new GetMovieByIdResponseDocument instance, which itself is finally wrapped into a SOAPMessage by importing the root DOM node into the message body.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Creating Provider-based endpoints makes it possible to use JAX-WS together with binding frameworks other than JAXB. Whether it should be done depends as always on the specific circumstances. &lt;/p&gt;

&lt;p&gt;For new projects working with SEI endpoints and therefore JAXB should be preferred. The JAX-WS tooling will smoothly generate JAXB binding classes as well as port type interfaces, making the creation of new web services pretty simple.&lt;/p&gt;

&lt;p&gt;In migration scenarios things can be different though. Re-writing a whole lot of mapping code originally created for another binding framework such as XmlBeans can be quite a time-consuming and error-prone task. In that case implementing Provider-based services can be an interesting alternative. &lt;/p&gt;

&lt;p&gt;When pursuing that approach some performance tests should be executed first. A short load test on my machine didn't show significant execution time differences between JAXB/XmlBeans for the video rental service. But things might look different for larger message types due to the involved DOM manipulations.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-5073159143288658535?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/q5BDa_p-XnY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/q5BDa_p-XnY/integrating-jax-ws-with-xmlbeans.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>2</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/02/integrating-jax-ws-with-xmlbeans.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-6865563692582809078</guid><pubDate>Sun, 17 Jan 2010 13:08:00 +0000</pubDate><atom:updated>2010-01-17T14:13:04.712+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">JSR 303</category><category domain="http://www.blogger.com/atom/ns#">design pattern</category><category domain="http://www.blogger.com/atom/ns#">Bean Validation</category><title>Implementing the Builder Pattern using the Bean Validation API</title><description>&lt;p&gt;In his excellent book &lt;a href="http://www.amazon.com/dp/0321356683/"&gt;"Effective Java (2nd edition)"&lt;/a&gt; Joshua Bloch describes a variation of the &lt;a href="http://en.wikipedia.org/wiki/Builder_pattern"&gt;Builder&lt;/a&gt; design pattern for instantiating objects with multiple optional attributes.&lt;/p&gt;

&lt;p&gt;Sticking to this pattern frees you from providing multiple constructors with the different optional attributes as parameters (hard to maintain and hard to read for clients) or providing setter methods for the optional attributes (require objects to be mutable, can leave objects in inconsistent state).&lt;/p&gt;

&lt;p&gt;As Bloch points out, it's a very good idea to check any invariants applying to the object to be created within the builder's build() method. That way it is ensured, that clients can only retrieve valid object instances from the builder. &lt;/p&gt;

&lt;p&gt;If you are using the Bean Validation API (&lt;a href="http://jcp.org/en/jsr/detail?id=303"&gt;JSR 303&lt;/a&gt;) to define constraints for your object model, this can be realized by validating these constraints within the build() method.&lt;/p&gt;

&lt;p&gt;The following listing shows an example:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;45&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;51&lt;tt&gt;
&lt;/tt&gt;52&lt;tt&gt;
&lt;/tt&gt;53&lt;tt&gt;
&lt;/tt&gt;54&lt;tt&gt;
&lt;/tt&gt;55&lt;tt&gt;
&lt;/tt&gt;56&lt;tt&gt;
&lt;/tt&gt;57&lt;tt&gt;
&lt;/tt&gt;58&lt;tt&gt;
&lt;/tt&gt;59&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;61&lt;tt&gt;
&lt;/tt&gt;62&lt;tt&gt;
&lt;/tt&gt;63&lt;tt&gt;
&lt;/tt&gt;64&lt;tt&gt;
&lt;/tt&gt;65&lt;tt&gt;
&lt;/tt&gt;66&lt;tt&gt;
&lt;/tt&gt;67&lt;tt&gt;
&lt;/tt&gt;68&lt;tt&gt;
&lt;/tt&gt;69&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;70&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;71&lt;tt&gt;
&lt;/tt&gt;72&lt;tt&gt;
&lt;/tt&gt;73&lt;tt&gt;
&lt;/tt&gt;74&lt;tt&gt;
&lt;/tt&gt;75&lt;tt&gt;
&lt;/tt&gt;76&lt;tt&gt;
&lt;/tt&gt;77&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Customer&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;long&lt;/span&gt; id;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; firstName;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; lastName;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;Date&lt;/span&gt; birthday;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; Customer(Builder builder) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.id = builder.id;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.firstName = builder.firstName;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.lastName = builder.lastName;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.birthday = builder.birthday;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Builder&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;Validator&lt;/span&gt; validator = &lt;tt&gt;
&lt;/tt&gt;            Validation.buildDefaultValidatorFactory().getValidator();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;long&lt;/span&gt; id;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; firstName;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; lastName;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;Date&lt;/span&gt; birthday;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="di"&gt;public&lt;/span&gt; Builder(&lt;span class="ty"&gt;long&lt;/span&gt; id, &lt;span class="ty"&gt;String&lt;/span&gt; lastName) {&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="lv"&gt;this&lt;/span&gt;.id = id;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="lv"&gt;this&lt;/span&gt;.lastName = lastName;&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="di"&gt;public&lt;/span&gt; Builder firstName(&lt;span class="ty"&gt;String&lt;/span&gt; firstName) {&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="lv"&gt;this&lt;/span&gt;.firstName = firstName;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="lv"&gt;this&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="di"&gt;public&lt;/span&gt; Builder birthday(&lt;span class="ty"&gt;Date&lt;/span&gt; birthday) {&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="lv"&gt;this&lt;/span&gt;.birthday = birthday;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="lv"&gt;this&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="di"&gt;public&lt;/span&gt; Customer build() &lt;span class="di"&gt;throws&lt;/span&gt; ConstraintViolationException {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;            Customer customer = &lt;span class="kw"&gt;new&lt;/span&gt; Customer(&lt;span class="lv"&gt;this&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ty"&gt;Set&lt;/span&gt;&amp;lt;ConstraintViolation&amp;lt;Customer&amp;gt;&amp;gt; violations = &lt;tt&gt;
&lt;/tt&gt;                validator.validate(customer);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;if&lt;/span&gt; (!violations.isEmpty()) {&lt;tt&gt;
&lt;/tt&gt;                &lt;span class="kw"&gt;throw&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; ConstraintViolationException(&lt;tt&gt;
&lt;/tt&gt;                    &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;HashSet&lt;/span&gt;&amp;lt;ConstraintViolation&amp;lt;?&amp;gt;&amp;gt;(violations));&lt;tt&gt;
&lt;/tt&gt;            }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;return&lt;/span&gt; customer;&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Min&lt;/span&gt;(&lt;span class="i"&gt;1&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;long&lt;/span&gt; getId() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; id;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Size&lt;/span&gt;(min = &lt;span class="i"&gt;3&lt;/span&gt;, max = &lt;span class="i"&gt;80&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; getFirstName() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; firstName;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Size&lt;/span&gt;(min = &lt;span class="i"&gt;3&lt;/span&gt;, max = &lt;span class="i"&gt;80&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@NotNull&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; getLastName() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; lastName;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Past&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;Date&lt;/span&gt; getBirthday() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; birthday;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;The listing shows an exemplary model class Customer for which some invariants apply (e.g. a customer's last name must not be null and must be between 3 and 80 characters long). These invariants are expressed using constraint annotations from the Bean Validation API at the getter methods of the Customer class.&lt;/p&gt;

&lt;p&gt;The inner class Builder is in charge of creating Customer instances. All mandatory fields &amp;#150; either primitive (e.g. id) or annotated with @NotNull (e.g. lastName) &amp;#150; are part of the builder's constructor. For all optional fields setter methods on the builder are provided.&lt;/p&gt;

&lt;p&gt;Within the build() method the newly created Customer instance is validated using the &lt;a href="http://java.sun.com/javaee/6/docs/api/javax/validation/Validator.html#validate(T,%20java.lang.Class...)"&gt;Validator#validate()&lt;/a&gt; method. If any constraint violations occur, a ConstraintViolationException is thrown. That way it's impossible to retrieve an invalid Customer instance. The following unit test shows an example:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;CustomerTest&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Test&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; validCustomer() {&lt;tt&gt;
&lt;/tt&gt;        Customer c = &lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;new&lt;/span&gt; Customer.Builder(&lt;span class="i"&gt;1&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Smith&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;                .firstName(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;                .birthday(&lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;GregorianCalendar&lt;/span&gt;(&lt;span class="i"&gt;1970&lt;/span&gt;, &lt;span class="i"&gt;3&lt;/span&gt;, &lt;span class="i"&gt;10&lt;/span&gt;).getTime())&lt;tt&gt;
&lt;/tt&gt;                .build();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        assertNotNull(c);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Test&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; lastNameNullAndBirthdayInFuture() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;try&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;new&lt;/span&gt; Customer.Builder(&lt;span class="i"&gt;1&lt;/span&gt;, &lt;span class="kw"&gt;null&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;                .birthday(&lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;GregorianCalendar&lt;/span&gt;(&lt;span class="i"&gt;2020&lt;/span&gt;, &lt;span class="i"&gt;3&lt;/span&gt;, &lt;span class="i"&gt;10&lt;/span&gt;).getTime())&lt;tt&gt;
&lt;/tt&gt;                .build();&lt;tt&gt;
&lt;/tt&gt;            fail(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Expected ConstraintViolationException wasn't thrown.&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;catch&lt;/span&gt; (ConstraintViolationException e) {&lt;tt&gt;
&lt;/tt&gt;            assertEquals(&lt;span class="i"&gt;2&lt;/span&gt;, e.getConstraintViolations().size());&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;If there are multiple classes for which you want to provide a builder in the described way, it is useful to extract the validation routine into a base class:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;abstract&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;AbstractBuilder&lt;/span&gt;&amp;lt;T&amp;gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;Validator&lt;/span&gt; validator = &lt;tt&gt;
&lt;/tt&gt;        Validation.buildDefaultValidatorFactory().getValidator();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;protected&lt;/span&gt; &lt;span class="di"&gt;abstract&lt;/span&gt; T buildInternal();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; T build() &lt;span class="di"&gt;throws&lt;/span&gt; ConstraintViolationException {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        T object = buildInternal();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ty"&gt;Set&lt;/span&gt;&amp;lt;ConstraintViolation&amp;lt;T&amp;gt;&amp;gt; violations = validator.validate(object);&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (!violations.isEmpty()) {&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;throw&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; ConstraintViolationException(&lt;tt&gt;
&lt;/tt&gt;                &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;HashSet&lt;/span&gt;&amp;lt;ConstraintViolation&amp;lt;?&amp;gt;&amp;gt;(violations));&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; object;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Concrete builder classes have to extend AbstractBuilder and must implement the buildInternal() method:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;public &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Builder&lt;/span&gt; &lt;span class="di"&gt;extends&lt;/span&gt; AbstractBuilder&amp;lt;Customer&amp;gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;long&lt;/span&gt; id;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; firstName;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; lastName;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;Date&lt;/span&gt; birthday;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; Builder(&lt;span class="ty"&gt;long&lt;/span&gt; id, &lt;span class="ty"&gt;String&lt;/span&gt; lastName) {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.id = id;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.lastName = lastName;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; Builder firstName(&lt;span class="ty"&gt;String&lt;/span&gt; firstName) {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.firstName = firstName;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="lv"&gt;this&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; Builder birthday(&lt;span class="ty"&gt;Date&lt;/span&gt; birthday) {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.birthday = birthday;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="lv"&gt;this&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;protected&lt;/span&gt; Customer buildInternal() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; Customer(&lt;span class="lv"&gt;this&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;The complete source code for this post can be found in my &lt;a href="http://github.com/gunnarmorling/musings-of-a-programming-addict/tree/master/builder-pattern/"&gt;Git repository&lt;/a&gt; over at &lt;a href="http://github.com/"&gt;github.com&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-6865563692582809078?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/G4IQJBV8uJg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/G4IQJBV8uJg/implementing-builder-pattern-using-bean.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>4</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/01/implementing-builder-pattern-using-bean.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-651320578271679706</guid><pubDate>Tue, 05 Jan 2010 23:27:00 +0000</pubDate><atom:updated>2010-01-06T18:41:11.171+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">JPA 2</category><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">JSR 303</category><category domain="http://www.blogger.com/atom/ns#">Bean Validation</category><category domain="http://www.blogger.com/atom/ns#">Maven</category><category domain="http://www.blogger.com/atom/ns#">JSR 317</category><title>JPA 2 and Bean Validation in Action</title><description>&lt;p&gt;Version 2 of the Java Persistence API (&lt;a href="http://jcp.org/en/jsr/detail?id=317"&gt;JPA&lt;/a&gt;) comes with an out-of-the-box integration of the Bean Validation API (&lt;a href="http://jcp.org/en/jsr/detail?id=317"&gt;BV&lt;/a&gt;). If a BV implementation is found in the runtime environment, any BV constraints placed at JPA entities will be validated whenever an entity is written to the database. In the following I'm going to show how the both APIs play together. &lt;/p&gt;

&lt;h2&gt;Project setup&lt;/h2&gt;

&lt;p&gt;Assuming you are working with Apache &lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt;, begin by adding the following repositories to your settings.xml or the pom.xml of your project:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;repository&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;JBoss Repo&lt;span class="ta"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;http://repository.jboss.com/maven2&lt;span class="ta"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/repository&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;repository&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;EclipseLink Repo&lt;span class="ta"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;http://www.eclipse.org/downloads/download.php?r=1&lt;span class="er"&gt;&amp;amp;&lt;/span&gt;nf=1&lt;span class="er"&gt;&amp;amp;&lt;/span&gt;file=/rt/eclipselink/maven.repo&lt;span class="ta"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/repository&amp;gt;&lt;/span&gt;   &lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;In order to use the reference implementations of both APIs (&lt;a href="http://www.eclipse.org/eclipselink/jpa.php"&gt;EclipseLink&lt;/a&gt; resp. &lt;a href="https://www.hibernate.org/412.html"&gt;Hibernate Validator&lt;/a&gt;) add the following dependencies to you pom.xml:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;&amp;lt;!-- JPA API and RI --&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;javax.persistence&lt;span class="ta"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;javax.persistence&lt;span class="ta"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0-SNAPSHOT&lt;span class="ta"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;compile&lt;span class="ta"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.eclipse.persistence&lt;span class="ta"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;eclipselink&lt;span class="ta"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0.0&lt;span class="ta"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="ta"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;&amp;lt;!-- Bean Validation API and RI --&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;javax.validation&lt;span class="ta"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;validation-api&lt;span class="ta"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.0.GA&lt;span class="ta"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;compile&lt;span class="ta"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.hibernate&lt;span class="ta"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;hibernate-validator&lt;span class="ta"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;4.0.2.GA&lt;span class="ta"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="ta"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.slf4j&lt;span class="ta"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;slf4j-jdk14&lt;span class="ta"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.5.6&lt;span class="ta"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="ta"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Instead of EclipseLink you might also use &lt;a href="https://www.hibernate.org/344.html"&gt;Hibernate 3.5&lt;/a&gt; (currently beta) as JPA provider:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.hibernate.java-persistence&lt;span class="ta"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;jpa-api&lt;span class="ta"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0-cr-1&lt;span class="ta"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;compile&lt;span class="ta"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.hibernate&lt;span class="ta"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;hibernate-entitymanager&lt;span class="ta"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.5.0-Beta-2&lt;span class="ta"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="ta"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Finally we need a database to execute some unit tests against it. I recommend using &lt;a href="http://db.apache.org/derby/"&gt;Apache Derby&lt;/a&gt; as it provides an in-memory mode, which is perfectly suited for unit tests:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.derby&lt;span class="ta"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;derby&lt;span class="ta"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;10.5.3.0_1&lt;span class="ta"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="ta"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;h2&gt;The model class&lt;/h2&gt;

&lt;p&gt;Now let's create a simple model class. It's just a POJO with some annotations stemming from JPA (@Entity, @Id etc.) and some from Bean Validation (@NotNull, @Size):&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="at"&gt;@Entity&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@NamedQueries&lt;/span&gt;( { &lt;span class="at"&gt;@NamedQuery&lt;/span&gt;(name = Customer.FIND_ALL_CUSTOMERS, query = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;SELECT c FROM Customer c&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) })&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Customer&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;final&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; FIND_ALL_CUSTOMERS = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;findAllCustomers&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Id&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@GeneratedValue&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@NotNull&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;Long&lt;/span&gt; id;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@NotNull&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Size&lt;/span&gt;(min = &lt;span class="i"&gt;3&lt;/span&gt;, max = &lt;span class="i"&gt;80&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; name;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;boolean&lt;/span&gt; archived;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; Customer() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; Customer(&lt;span class="ty"&gt;String&lt;/span&gt; name) {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.name = name;&lt;tt&gt;
&lt;/tt&gt;        archived = &lt;span class="kw"&gt;false&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;//getters and setters ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;h2&gt;Configuration&lt;/h2&gt;

&lt;p&gt;Next we have to setup the file persistence.xml which defines the persistence unit to be used for our module tests:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="pp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;persistence&lt;/span&gt; &lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xmlns&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://java.sun.com/xml/ns/persistence&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xmlns:xsi&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;xsi:schemaLocation&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="an"&gt;version&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;2.0&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;persistence-unit&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;testPU&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;transaction-type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;RESOURCE_LOCAL&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ta"&gt;&amp;lt;class&amp;gt;&lt;/span&gt;de.gmorling.jpa2.model.Customer&lt;span class="ta"&gt;&amp;lt;/class&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ta"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;eclipselink.target-database&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;value&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;DERBY&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;eclipselink.ddl-generation&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;value&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;create-tables&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;javax.persistence.jdbc.driver&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;value&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;org.apache.derby.jdbc.EmbeddedDriver&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;javax.persistence.jdbc.url&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;value&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;jdbc:derby:memory:testDB;create=true&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;javax.persistence.jdbc.user&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;value&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;APP&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ta"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;javax.persistence.jdbc.password&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;value&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;APP&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ta"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;/persistence-unit&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/persistence&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;JPA 2 standardizes the property names for driver, user etc. When working with EclipseLink therefore only two provider-specific properties for the target database and the DDL strategy are required.&lt;/p&gt;

&lt;p&gt;Using Hibernate the properties would look like the following (at the time of writing this post the standard properties don't seem to be supported yet by Hibernate):&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hibernate.dialect&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;value&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;org.hibernate.dialect.DerbyDialect&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hibernate.hbm2ddl.auto&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;value&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;create&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hibernate.connection.driver_class&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;value&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;org.apache.derby.jdbc.EmbeddedDriver&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hibernate.connection.username&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;value&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;APP&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hibernate.connection.password&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;value&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;APP&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hibernate.connection.url&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;value&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;jdbc:derby:memory:testDB;create=true&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Note that not a single line of configuration is required to enable the Bean Validation integration, it's working out of the box. If JPA detects a BV implementation on the classpath, it will use it by default to validate any BV constraints, whenever an entity is persisted or updated.&lt;/p&gt;

&lt;h2&gt;And action ...&lt;/h2&gt;

&lt;p&gt;To try that, let's write a simple unit test for our model class:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;45&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;51&lt;tt&gt;
&lt;/tt&gt;52&lt;tt&gt;
&lt;/tt&gt;53&lt;tt&gt;
&lt;/tt&gt;54&lt;tt&gt;
&lt;/tt&gt;55&lt;tt&gt;
&lt;/tt&gt;56&lt;tt&gt;
&lt;/tt&gt;57&lt;tt&gt;
&lt;/tt&gt;58&lt;tt&gt;
&lt;/tt&gt;59&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;61&lt;tt&gt;
&lt;/tt&gt;62&lt;tt&gt;
&lt;/tt&gt;63&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;CustomerTest&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; EntityManagerFactory emf;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; EntityManager em;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@BeforeClass&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; createEntityManagerFactory() {&lt;tt&gt;
&lt;/tt&gt;        emf = Persistence.createEntityManagerFactory(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;testPU&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@AfterClass&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; closeEntityManagerFactory() {&lt;tt&gt;
&lt;/tt&gt;        emf.close();&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Before&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; beginTransaction() {&lt;tt&gt;
&lt;/tt&gt;        em = emf.createEntityManager();&lt;tt&gt;
&lt;/tt&gt;        em.getTransaction().begin();&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@After&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; rollbackTransaction() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (em.getTransaction().isActive())&lt;tt&gt;
&lt;/tt&gt;            em.getTransaction().rollback();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (em.isOpen())&lt;tt&gt;
&lt;/tt&gt;            em.close();&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Test&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; nameTooShort() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;try&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;            Customer customer = &lt;span class="kw"&gt;new&lt;/span&gt; Customer(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Bo&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;            em.persist(customer);&lt;tt&gt;
&lt;/tt&gt;            fail(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Expected ConstraintViolationException wasn't thrown.&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        } &lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;catch&lt;/span&gt; (ConstraintViolationException e) {&lt;tt&gt;
&lt;/tt&gt;            assertEquals(&lt;span class="i"&gt;1&lt;/span&gt;, e.getConstraintViolations().size());&lt;tt&gt;
&lt;/tt&gt;            ConstraintViolation&amp;lt;?&amp;gt; violation = &lt;tt&gt;
&lt;/tt&gt;                e.getConstraintViolations().iterator().next();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;            assertEquals(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, violation.getPropertyPath().toString());&lt;tt&gt;
&lt;/tt&gt;            assertEquals(&lt;tt&gt;
&lt;/tt&gt;                Size.class, &lt;tt&gt;
&lt;/tt&gt;                violation.getConstraintDescriptor().getAnnotation().annotationType());&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Test&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; validCustomer() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        Customer customer = &lt;span class="kw"&gt;new&lt;/span&gt; Customer(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        em.persist(customer);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ty"&gt;Query&lt;/span&gt; query = em.createNamedQuery(Customer.FIND_ALL_CUSTOMERS);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        assertEquals(&lt;span class="i"&gt;1&lt;/span&gt;, query.getResultList().size());&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;The first four methods are just for setting up resp. closing down an entity manager factory for our persistence unit as well as the entity manager to be used. &lt;/p&gt;

&lt;p&gt;In the test method nameTooShort() a ConstraintViolationException is raised, as the @Size constraint of the "name" attribute isn't fulfilled. The method validCustomer() on the other hand shows how a valid Customer instance is persisted and successfully retrieved later on.&lt;/p&gt;

&lt;h2&gt;Specifying validation groups&lt;/h2&gt;

&lt;p&gt;By default the constraint annotations of the &lt;a href="http://java.sun.com/javaee/6/docs/api/javax/validation/groups/Default.html"&gt;Default&lt;/a&gt; validation group are validated upon inserting a new entity. The same holds true when an existing entity is updated, while no validation takes place by default if an entity is deleted.&lt;/p&gt;

&lt;p&gt;If needed this behavior can be overridden by specifying the following properties in the persistence.xml (where values must be comma separated lists of fully-qualified class names of the groups to be validated):&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;javax.persistence.validation.group.pre-persist&lt;tt&gt;
&lt;/tt&gt;javax.persistence.validation.group.pre-update&lt;tt&gt;
&lt;/tt&gt;javax.persistence.validation.group.pre-remove&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Let's assume for example that when a customer account is closed the concerned record from the Customer table is moved to some kind of archive storage. For all migrated records the "archived" flag should be set to true. Using a constraint annotation we would like to ensure now, that only archived Customer records are allowed to be deleted.&lt;/p&gt;

&lt;p&gt;To do so we first define a new validation group by declaring an empty interface:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;interface&lt;/span&gt; DeletionAttributes {}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Now we add an @AssertTrue constraint to the "archived" attribute, which is part of this validation group:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Customer&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    ...&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@AssertTrue&lt;/span&gt;(groups = DeletionAttributes.class)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;boolean&lt;/span&gt; archived;&lt;tt&gt;
&lt;/tt&gt;    ...&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Then we specify that constraints of the DeletionAttributes group shall be evaluated upon entity removal:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;javax.persistence.validation.group.pre-remove&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;value&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;de.gmorling.jpa2.model.DeletionAttributes&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="ta"&gt;/&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;As an unit test shows, a ConstraintViolationException will be raised now, if we try to delete a non-archived customer:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@Test&lt;/span&gt;(expected = ConstraintViolationException.class)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; nonArchivedCustomerDeleted() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    Customer customer = &lt;span class="kw"&gt;new&lt;/span&gt; Customer(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;    em.persist(customer);&lt;tt&gt;
&lt;/tt&gt;    em.remove(customer);&lt;tt&gt;
&lt;/tt&gt;}...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;But everything will be fine, if an archived customer gets deleted:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;span class="at"&gt;@Test&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; archivedCustomerDeleted() {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    Customer customer = &lt;span class="kw"&gt;new&lt;/span&gt; Customer(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;    em.persist(customer);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    customer.setArchived(&lt;span class="kw"&gt;true&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;    em.remove(customer);&lt;tt&gt;
&lt;/tt&gt;    assertTrue(&lt;tt&gt;
&lt;/tt&gt;        em.createNamedQuery(Customer.FIND_ALL_CUSTOMERS).getResultList().isEmpty());&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Specifying the validation groups to be evaluated allows a very fine-grained configuration of the constraint checking process. But there might also be situations where you don't want any validation to take place at all. In that case the validation can be turned off completely by setting the validation mode to "NONE" within your persistence.xml:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;persistence-unit&lt;/span&gt; &lt;span class="an"&gt;name&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;testPU&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="an"&gt;transaction-type&lt;/span&gt;=&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;RESOURCE_LOCAL&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="ta"&gt;&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;validation-mode&amp;gt;&lt;/span&gt;NONE&lt;span class="ta"&gt;&amp;lt;/validation-mode&amp;gt;&lt;/span&gt; &lt;tt&gt;
&lt;/tt&gt;    ...&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/persistence-unit&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;As this post shows, JPA and BV API are integrated very well. Validating your entities before they are written to the database is a very powerful tool for improving data quality, as it ensures that all your persisted data adheres to the constraints of your object model. &lt;/p&gt;

&lt;p&gt;I really recommend you to try it out yourself and of course I would be very happy on any feedback.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-651320578271679706?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/-vOj6fFkGeE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/-vOj6fFkGeE/jpa-2-and-bean-validation-in-action.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>8</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/01/jpa-2-and-bean-validation-in-action.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-2767854817044060439</guid><pubDate>Sun, 03 Jan 2010 19:39:00 +0000</pubDate><atom:updated>2010-01-03T20:40:29.404+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">statistics</category><category domain="http://www.blogger.com/atom/ns#">Blog</category><title>2009 in numbers</title><description>&lt;p&gt;2009 was my first complete year of blogging, so I thought it might be the right time to present some statistics of the last 12 months:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;17,738 visits total&lt;/li&gt;
&lt;li&gt;25,394 page views total&lt;/li&gt;
&lt;li&gt;best month: March (1,958 visits)&lt;/li&gt;
&lt;li&gt;best day: March, 13 th (335 visits due to the &lt;a href="http://www.adam-bien.com/roller/abien/entry/ejb_3_and_guice_just"&gt;Adam Bien&lt;/a&gt; effect ;-))&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These were the most visited posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://musingsofaprogrammingaddict.blogspot.com/2009/01/getting-started-with-jsr-303-beans.html"&gt;Getting started with JSR 303 (Bean Validation) &amp;#150; part 1&lt;/a&gt; (4,332 views)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://musingsofaprogrammingaddict.blogspot.com/2009/03/guice-tutorial-part-3-integrating-guice.html"&gt;Guice Tutorial part 3 &amp;#150; Integrating Guice with EJB&lt;/a&gt; (3,148 views)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://musingsofaprogrammingaddict.blogspot.com/2009/03/writing-and-testing-jax-ws-clients.html"&gt;Writing and testing JAX-WS clients using the Spring framework&lt;/a&gt; (2,129 views)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The visitors came from 118 different countries, the top 5 being:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;United States: 26.18%    &lt;/li&gt;
&lt;li&gt;Germany: 14.95%  &lt;/li&gt;
&lt;li&gt;United Kingdom: 7.00%    &lt;/li&gt;
&lt;li&gt;France 4.71%     &lt;/li&gt;
&lt;li&gt;India: 3.00%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you all for reading and commenting. Stay tuned :-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-2767854817044060439?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/Qr8bL5-Se1k" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/Qr8bL5-Se1k/2009-in-numbers.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>0</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2010/01/2009-in-numbers.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-5139212762196820889</guid><pubDate>Thu, 31 Dec 2009 16:36:00 +0000</pubDate><atom:updated>2009-12-31T17:40:03.548+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">Jetty</category><category domain="http://www.blogger.com/atom/ns#">Maven</category><category domain="http://www.blogger.com/atom/ns#">JSF 2</category><title>Running JSF 2 on embedded Jetty</title><description>&lt;p&gt;&lt;a href="http://jetty.codehaus.org/jetty/"&gt;Jetty&lt;/a&gt; is widely appreciated as low-footprint and lightning-fast web container. That makes it also a perfect fit to be used as development runtime, where short turnaround times are an absolut must.&lt;/p&gt;

&lt;p&gt;I used to work with the &lt;a href="http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin"&gt;Jetty Maven plugin&lt;/a&gt;, which supports hot-deploying applications after any code changes while Jetty is running. This works pretty well, but comes at the cost that your session data is lost during re-deployment and depending on your application's complexity it also can take some seconds to get it up running again.&lt;/p&gt;

&lt;p&gt;So I tried another option: running Jetty in &lt;a href="http://docs.codehaus.org/display/JETTY/Embedding+Jetty"&gt;embedded mode&lt;/a&gt;. For that purpose Jetty provides a comprehensive &lt;a href="http://download.eclipse.org/jetty/stable-7/apidocs/"&gt;API&lt;/a&gt;, which we can use to write a simple main class that starts up a Jetty instance serving the application we are currently developing:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;JettyRunner&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; main(&lt;span class="ty"&gt;String&lt;/span&gt;&lt;span class="ty"&gt;[]&lt;/span&gt; args) &lt;span class="di"&gt;throws&lt;/span&gt; &lt;span class="ty"&gt;Exception&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        Server server = &lt;span class="kw"&gt;new&lt;/span&gt; Server();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        Connector connector = &lt;span class="kw"&gt;new&lt;/span&gt; SelectChannelConnector();&lt;tt&gt;
&lt;/tt&gt;        connector.setPort(&lt;span class="i"&gt;8080&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        connector.setHost(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;127.0.0.1&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        server.addConnector(connector);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        WebAppContext wac = &lt;span class="kw"&gt;new&lt;/span&gt; WebAppContext();&lt;tt&gt;
&lt;/tt&gt;        wac.setContextPath(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/myapp&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        wac.setBaseResource(&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;new&lt;/span&gt; ResourceCollection(&lt;tt&gt;
&lt;/tt&gt;                &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt;&lt;span class="ty"&gt;[]&lt;/span&gt; {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;./src/main/webapp&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}));&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        server.setHandler(wac);&lt;tt&gt;
&lt;/tt&gt;        server.setStopAtShutdown(&lt;span class="kw"&gt;true&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        server.start();&lt;tt&gt;
&lt;/tt&gt;        server.join();&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;The code is pretty much straight forward: first a connector with port and hostname is configured, then a context for the application is created and registered with the server, which finally is started up.&lt;/p&gt;

&lt;p&gt;When we launch this class in debugging mode from within our IDE, code changes are immediately applied to the running application without the need to re-deploy or restart it due to Java's &lt;a href="http://wiki.eclipse.org/FAQ_What_is_hot_code_replace%3F"&gt;hot code replacement&lt;/a&gt; mechanism.&lt;/p&gt;

&lt;p&gt;Furthermore all changes to the files under "src/main/webapp" are instantly visible, as the files are served directly from there.&lt;/p&gt;

&lt;p&gt;The reduced number of required restarts/redeployments greatly improves development productivity. Basically restarting is only required when modifying deployment descriptors (such as web.xml) or when class signatures are modified (e.g. by adding new methods).&lt;/p&gt;

&lt;h2&gt;Running JSF applications&lt;/h2&gt;

&lt;p&gt;This works like a charm for basic servlets, but things are getting a bit more complicated, when &lt;a href="http://java.sun.com/javaee/javaserverfaces/"&gt;JSF&lt;/a&gt; comes into play.&lt;/p&gt;

&lt;p&gt;The reason is that JSF searches for all classes carrying any of the JSF annotations (such as @ManagedBean) when starting up. This scan takes place in the directory "META-INF/classes". As this folder doesn't exist in our case, no single managed bean will be detected.&lt;/p&gt;

&lt;p&gt;How can this problem be solved? First of all the output folder of the application must be added to the WebAppContext's resource collection. In case of a Maven-based project we have to add the "target" directory:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;wac.setBaseResource(&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="kw"&gt;new&lt;/span&gt; ResourceCollection(&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt;&lt;span class="ty"&gt;[]&lt;/span&gt; { &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;./src/main/webapp&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;./target&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; }));&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;But the problem remains that JSF searches class files in "WEB-INF/classes", although in our case they are located under "classes".&lt;/p&gt;

&lt;p&gt;We could modify the destination of class files (by setting Maven's &lt;a href="http://docs.codehaus.org/display/MAVENUSER/MavenPropertiesGuide"&gt;property ${project.build.outputDirectory}&lt;/a&gt;, but I wouldn't really recommend this. Diverging from Maven's conventions makes your project harder to understand for other developers and as rumors go there still are Maven plugins around that directly access "target/classes" instead of referencing said property.&lt;/p&gt;

&lt;h2&gt;Resource aliases&lt;/h2&gt;

&lt;p&gt;I studied Jetty's API for a while and came across the concept of &lt;a href="http://download.eclipse.org/jetty/stable-7/apidocs/org/eclipse/jetty/webapp/WebAppContext.html#setResourceAlias(java.lang.String,%20java.lang.String"&gt;resource aliases&lt;/a&gt; which provides a neat solution to our problem. To define an alias for "WEB-INF/classes" just do the following:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;WebAppContext wac = &lt;span class="kw"&gt;new&lt;/span&gt; WebAppContext();&lt;tt&gt;
&lt;/tt&gt;wac.setResourceAlias(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/WEB-INF/classes/&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/classes/&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Unfortunately this only works for single resources. While everything is fine when the folder "WEB-INF/classes" itself is accessed, the alias won't be applied when accessing resources contained within this folder, e.g. "WEB-INF/classes/MyManagedBean.class".&lt;/p&gt;

&lt;p&gt;To tackle this problem I extended Jetty's WebAppContext to provide a means of pattern based alias resolution. The only overridden method is getResourceAlias():&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;AliasEnhancedWebAppContext&lt;/span&gt; &lt;span class="di"&gt;extends&lt;/span&gt; WebAppContext {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; getResourceAlias(&lt;span class="ty"&gt;String&lt;/span&gt; alias) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="at"&gt;@SuppressWarnings&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;unchecked&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ty"&gt;Map&lt;/span&gt;&amp;lt;&lt;span class="ty"&gt;String&lt;/span&gt;, &lt;span class="ty"&gt;String&lt;/span&gt;&amp;gt; resourceAliases = &lt;tt&gt;
&lt;/tt&gt;            (&lt;span class="ty"&gt;Map&lt;/span&gt;&amp;lt;&lt;span class="ty"&gt;String&lt;/span&gt;, &lt;span class="ty"&gt;String&lt;/span&gt;&amp;gt;) getResourceAliases();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (resourceAliases == &lt;span class="kw"&gt;null&lt;/span&gt;) {&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;null&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;for&lt;/span&gt; (Entry&amp;lt;&lt;span class="ty"&gt;String&lt;/span&gt;, &lt;span class="ty"&gt;String&lt;/span&gt;&amp;gt; oneAlias : &lt;tt&gt;
&lt;/tt&gt;            resourceAliases.entrySet()) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;if&lt;/span&gt; (alias.startsWith(oneAlias.getKey())) {&lt;tt&gt;
&lt;/tt&gt;                &lt;span class="kw"&gt;return&lt;/span&gt; alias.replace(&lt;tt&gt;
&lt;/tt&gt;                    oneAlias.getKey(), oneAlias.getValue());&lt;tt&gt;
&lt;/tt&gt;            }&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;null&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Whenever an alias for a given resource is looked up, it is checked whether the resource name starts with one of the registered aliases. If that's the case, the aliased part will be replaced. Having registered the alias from the previous listing, e.g. "WEB-INF/classes/MyManagedBean.class" will be aliased with "classes/MyManagedBean.class".&lt;/p&gt;

&lt;p&gt;It's certainly not perfect (e.g. nested replacements are not considered), but I would regard it good enough for being used in the scenario at hand. So let's look how all this fits together:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;JettyRunner&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; main(&lt;span class="ty"&gt;String&lt;/span&gt;&lt;span class="ty"&gt;[]&lt;/span&gt; args) &lt;span class="di"&gt;throws&lt;/span&gt; &lt;span class="ty"&gt;Exception&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        Server server = &lt;span class="kw"&gt;new&lt;/span&gt; Server();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        Connector connector = &lt;span class="kw"&gt;new&lt;/span&gt; SelectChannelConnector();&lt;tt&gt;
&lt;/tt&gt;        connector.setPort(&lt;span class="i"&gt;8080&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        connector.setHost(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;127.0.0.1&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        server.addConnector(connector);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        WebAppContext wac = &lt;span class="kw"&gt;new&lt;/span&gt; AliasEnhancedWebAppContext();&lt;tt&gt;
&lt;/tt&gt;        wac.setContextPath(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/myapp&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        wac.setBaseResource(&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;new&lt;/span&gt; ResourceCollection(&lt;tt&gt;
&lt;/tt&gt;                &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt;&lt;span class="ty"&gt;[]&lt;/span&gt; {&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;./src/main/webapp&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;./target&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}));&lt;tt&gt;
&lt;/tt&gt;        wac.setResourceAlias(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/WEB-INF/classes/&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/classes/&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        server.setHandler(wac);&lt;tt&gt;
&lt;/tt&gt;        server.setStopAtShutdown(&lt;span class="kw"&gt;true&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        server.start();&lt;tt&gt;
&lt;/tt&gt;        server.join();&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;That way we are finally able to run a JSF application on an embedded Jetty instance, providing us with a very efficient way of development.&lt;/p&gt;

&lt;h2&gt;EL libraries&lt;/h2&gt;

&lt;p&gt;Unfortunately my happiness was short lasting as I ran into another problem: Using &lt;a href="http://blogs.sun.com/rlubke/entry/unified_expression_language_is_and"&gt;method parameters&lt;/a&gt; within EL expressions gave me parsing errors wrapped into a javax.faces.view.facelets.TagAttributeException.&lt;/p&gt;

&lt;p&gt;The reason is that method invocations with parameters are a feature of &lt;a href="http://jcp.org/aboutJava/communityprocess/mrel/jsr245/index.html"&gt;Unified EL version 2.2&lt;/a&gt; which is leveraged by JSF 2. As &lt;a href="http://weblogs.java.net/blog/cayhorstmann/archive/2009/12/29/jsf-20-and-tomcat"&gt;others&lt;/a&gt; already pointed out, you need to replace the EL JARs (API and impl) of you web container with the new ones.&lt;/p&gt;

&lt;p&gt;Using Maven this can be done by adding the following dependencies to your project's pom.xml (if required, add the java.net &lt;a href="http://download.java.net/maven/2"&gt;Maven repository&lt;/a&gt; to your settings.xml first):&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;javax.el&lt;span class="ta"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;el-api&lt;span class="ta"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.2&lt;span class="ta"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;compile&lt;span class="ta"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.glassfish.web&lt;span class="ta"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;el-impl&lt;span class="ta"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.2&lt;span class="ta"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="ta"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;When working with the JSF 2 reference implementation &lt;a href="https://javaserverfaces.dev.java.net/"&gt;Mojarra&lt;/a&gt; furthermore the expression factory to be used must be set to the one from the new EL implementation by specifying the following context parameter within your web.xml:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;context-param&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="ta"&gt;&amp;lt;param-name&amp;gt;&lt;/span&gt;com.sun.faces.expressionFactory&lt;span class="ta"&gt;&amp;lt;/param-name&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="ta"&gt;&amp;lt;param-value&amp;gt;&lt;/span&gt;com.sun.el.ExpressionFactoryImpl&lt;span class="ta"&gt;&amp;lt;/param-value&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/context-param&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Having done that, you are now able to use parametrized method invocations within EL expressions, which is especially useful when performing actions on the rows of a &lt;a href="https://javaserverfaces.dev.java.net/nonav/docs/2.0/pdldocs/facelets/h/dataTable.html"&gt;data table&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-5139212762196820889?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/GatMMIbONKI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/GatMMIbONKI/running-jsf-2-on-embedded-jetty.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>5</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2009/12/running-jsf-2-on-embedded-jetty.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-281028814439138710</guid><pubDate>Sat, 21 Nov 2009 15:52:00 +0000</pubDate><atom:updated>2009-11-22T13:13:31.490+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Type inference</category><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">DTO</category><category domain="http://www.blogger.com/atom/ns#">Generics</category><title>A generic and yet type-safe DTO - part 2</title><description>&lt;p&gt;In a &lt;a href="http://musingsofaprogrammingaddict.blogspot.com/2009/10/generic-and-still-type-safe-dto.html"&gt;recent post&lt;/a&gt; I presented a generic &lt;a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObject.html"&gt;DTO&lt;/a&gt; implementation which allows a type-safe way of accessing its contents.&lt;/p&gt;

&lt;p&gt;The presented approach reduces the efforts of writing a lot of dedicated DTOs but comes at the cost that it is not obvious, which attributes are allowed to be put into or can be retrieved from a given DTO instance. Therefore methods using such a generic DTO as parameter or return value define a rather loose contract.&lt;/p&gt;

&lt;p&gt;In the following I'm going to show a way to solve this problem. The basic idea is to introduce the concept of "attribute groups". Each attribute belongs to such a group, and each GenericDTO instance is created for exactly one attribute group.&lt;/p&gt;

&lt;p&gt;Let's first define a &lt;a href="http://en.wikipedia.org/wiki/Marker_interface_pattern"&gt;marker interface&lt;/a&gt; AttributeGroup from which all concrete attribute groups will derive:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;interface&lt;/span&gt; AttributeGroup {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;The Attribute class doesn't differ much from the version introduced in the first post. It's just parametrized with the type of group to which a given attribute belongs:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Attribute&lt;/span&gt;&amp;lt;G &lt;span class="di"&gt;extends&lt;/span&gt; AttributeGroup, T&amp;gt; &lt;span class="di"&gt;implements&lt;/span&gt; &lt;span class="ty"&gt;Serializable&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="di"&gt;final&lt;/span&gt; &lt;span class="ty"&gt;long&lt;/span&gt; serialVersionUID = &lt;span class="i"&gt;1L&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; name;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;Attribute&lt;/span&gt;(&lt;span class="ty"&gt;String&lt;/span&gt; name) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (name == &lt;span class="kw"&gt;null&lt;/span&gt;) {&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="kw"&gt;throw&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;IllegalArgumentException&lt;/span&gt;();&lt;tt&gt;
&lt;/tt&gt;        }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.name = name;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &amp;lt;F &lt;span class="di"&gt;extends&lt;/span&gt; AttributeGroup, S&amp;gt; &lt;span class="ty"&gt;Attribute&lt;/span&gt;&amp;lt;F, S&amp;gt; getInstance(&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ty"&gt;String&lt;/span&gt; name) {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;Attribute&lt;/span&gt;&amp;lt;F, S&amp;gt;(name);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; toString() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; name;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;// equals(), hashCode() ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;As in the previous post Attribute instances are declared as constants on interfaces, e.g. PersonAttributes. But now each of these interfaces extends AttributeGroup, while the Attribute instances are parametrized with the attribute group:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;interface&lt;/span&gt; PersonAttributes &lt;span class="di"&gt;extends&lt;/span&gt; AttributeGroup {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="di"&gt;final&lt;/span&gt; &lt;span class="ty"&gt;Attribute&lt;/span&gt;&amp;lt;PersonAttributes, &lt;span class="ty"&gt;String&lt;/span&gt;&amp;gt; FIRST_NAME = &lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ty"&gt;Attribute&lt;/span&gt;.getInstance(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;FIRST_NAME&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="di"&gt;final&lt;/span&gt; &lt;span class="ty"&gt;Attribute&lt;/span&gt;&amp;lt;PersonAttributes, &lt;span class="ty"&gt;Integer&lt;/span&gt;&amp;gt; AGE = &lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ty"&gt;Attribute&lt;/span&gt;.getInstance(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;AGE&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;public &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;OrderAttributes&lt;/span&gt; &lt;span class="di"&gt;implements&lt;/span&gt; AttributeGroup {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="di"&gt;final&lt;/span&gt; &lt;span class="ty"&gt;Attribute&lt;/span&gt;&amp;lt;OrderAttributes, &lt;span class="ty"&gt;Long&lt;/span&gt;&amp;gt; &lt;tt&gt;
&lt;/tt&gt;        TOTAL_PRICE = &lt;span class="ty"&gt;Attribute&lt;/span&gt;.getInstance(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;TOTAL_PRICE&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;Also the GenericDTO class now has a type parameter specifying for which attribute group a given instance is declared:&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;45&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;51&lt;tt&gt;
&lt;/tt&gt;52&lt;tt&gt;
&lt;/tt&gt;53&lt;tt&gt;
&lt;/tt&gt;54&lt;tt&gt;
&lt;/tt&gt;55&lt;tt&gt;
&lt;/tt&gt;56&lt;tt&gt;
&lt;/tt&gt;57&lt;tt&gt;
&lt;/tt&gt;58&lt;tt&gt;
&lt;/tt&gt;59&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;61&lt;tt&gt;
&lt;/tt&gt;62&lt;tt&gt;
&lt;/tt&gt;63&lt;tt&gt;
&lt;/tt&gt;64&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;GenericDTO&lt;/span&gt;&amp;lt;G &lt;span class="di"&gt;extends&lt;/span&gt; AttributeGroup&amp;gt; &lt;span class="di"&gt;implements&lt;/span&gt; &lt;span class="ty"&gt;Serializable&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="di"&gt;final&lt;/span&gt; &lt;span class="ty"&gt;long&lt;/span&gt; serialVersionUID = &lt;span class="i"&gt;1L&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;Class&lt;/span&gt;&amp;lt;G&amp;gt; attributeGroup;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="ty"&gt;Map&lt;/span&gt;&amp;lt;&lt;span class="ty"&gt;Attribute&lt;/span&gt;&amp;lt;G, ?&amp;gt;, &lt;span class="ty"&gt;Object&lt;/span&gt;&amp;gt; attributes = &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ty"&gt;LinkedHashMap&lt;/span&gt;&amp;lt;&lt;span class="ty"&gt;Attribute&lt;/span&gt;&amp;lt;G, ?&amp;gt;, &lt;span class="ty"&gt;Object&lt;/span&gt;&amp;gt;();&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; GenericDTO(&lt;span class="ty"&gt;Class&lt;/span&gt;&amp;lt;G&amp;gt; attributeGroup) {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;.attributeGroup = attributeGroup;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &amp;lt;B &lt;span class="di"&gt;extends&lt;/span&gt; AttributeGroup&amp;gt; GenericDTO&amp;lt;B&amp;gt; getInstance(&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="ty"&gt;Class&lt;/span&gt;&amp;lt;B&amp;gt; clazz) {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; GenericDTO&amp;lt;B&amp;gt;(clazz);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &amp;lt;T&amp;gt; GenericDTO&amp;lt;G&amp;gt; set(&lt;span class="ty"&gt;Attribute&lt;/span&gt;&amp;lt;G, T&amp;gt; identifier, T value) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        attributes.put(identifier, value);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="lv"&gt;this&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &amp;lt;T&amp;gt; T get(&lt;span class="ty"&gt;Attribute&lt;/span&gt;&amp;lt;G, T&amp;gt; identifier) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="at"&gt;@SuppressWarnings&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;unchecked&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;        T theValue = (T) attributes.get(identifier);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; theValue;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &amp;lt;T&amp;gt; T remove(&lt;span class="ty"&gt;Attribute&lt;/span&gt;&amp;lt;G, T&amp;gt; identifier) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="at"&gt;@SuppressWarnings&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;unchecked&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;        T theValue = (T) attributes.remove(identifier);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; theValue;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; clear() {&lt;tt&gt;
&lt;/tt&gt;        attributes.clear();&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;int&lt;/span&gt; size() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; attributes.size();&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;Set&lt;/span&gt;&amp;lt;&lt;span class="ty"&gt;Attribute&lt;/span&gt;&amp;lt;G, ?&amp;gt;&amp;gt; getAttributes() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; attributes.keySet();&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;boolean&lt;/span&gt; contains(&lt;span class="ty"&gt;Attribute&lt;/span&gt;&amp;lt;G, ?&amp;gt; identifier) {&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; attributes.containsKey(identifier);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="at"&gt;@Override&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;String&lt;/span&gt; toString() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; attributeGroup.getSimpleName() + &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt; [&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + attributes + &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;]&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;// equals(), hashCode() ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;That way it is now clear at compile time which attributes are supported by a given GenericDTO instance. &lt;/p&gt;

&lt;p&gt;When for instance having a GenericDTO&lt;personattributes&gt; instance at hand, only attributes of the PersonAttributes group can be put into this DTO or can be retrieved from it. Trying to insert attributes of another group will yield in a compiler error:&lt;/personattributes&gt;&lt;/p&gt;

&lt;div class="gmCode"&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;...&lt;tt&gt;
&lt;/tt&gt;GenericDTO dto = GenericDTO.getInstance(PersonAttributes.class);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;//that's fine&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;dto.set(PersonAttributes.FIRST_NAME, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).set(PersonAttributes.AGE, &lt;span class="i"&gt;28&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;//compiler error&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;dto.set(OrderAttributes.TOTAL_PRICE, &lt;span class="i"&gt;9990&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;...&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;By introducing the group concept Attribute declaration is a bit more verbose than in the first version, but real compile-time safety and more explicit contracts should be worth the effort, which is still way below than having to implement dedicated DTOs with getters and setters for each attribute as well as proper equals()-, hashCode()- and toString()-Methods.&lt;/p&gt;

&lt;p&gt;What do you think &amp;#150; is a generic DTO implemented that way a good idea? As always I'm looking forward to receiving your feedback.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-281028814439138710?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/V0XJu5gvjpA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/V0XJu5gvjpA/generic-and-still-type-safe-dto-part-2.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>8</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2009/11/generic-and-still-type-safe-dto-part-2.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-1306958590608174053.post-4003914766012662120</guid><pubDate>Sat, 07 Nov 2009 11:06:00 +0000</pubDate><atom:updated>2009-11-07T12:07:47.411+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">JSR 303</category><category domain="http://www.blogger.com/atom/ns#">Bean Validation</category><category domain="http://www.blogger.com/atom/ns#">Java Magazin</category><title>Article on Bean Validation API available for download</title><description>&lt;p&gt;My article "Objekt: Zur Prüfung bitte!" covering the Bean Validation API (&lt;a href="http://jcp.org/en/jsr/detail?id=303"&gt;JSR 303&lt;/a&gt;) is available for &lt;a href="http://sites.google.com/site/musingsofaprogrammingaddict/files/JM_9_09_Objekt_zur_Pruefung_bitte.pdf?attredirects=0" onclick="javascript: pageTracker._trackPageview ('/downloads/JM_9_09_Objekt_zur_Pruefung_bitte');"&gt;download&lt;/a&gt; now. It originally appeared in &lt;a href="http://it-republik.de/jaxenter/java-magazin-ausgaben/JavaFX-lernt-das-Twittern-000315.html"&gt;Java Magazin 09.09&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since the time of writing JSR 303 reached its final state, but besides some minor changes the article is still up to date (e.g. it's "Payload" instead of "ConstraintPayload" now). More in-depth information on using the Bean Validation API and its reference implementation &lt;a href="http://validator.hibernate.org/"&gt;Hibernate Validator 4&lt;/a&gt; can be found in Hibernate Validator's &lt;a href="http://docs.jboss.org/hibernate/stable/validator/reference/en/html_single/"&gt;reference guide&lt;/a&gt;, which I co-authored.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1306958590608174053-4003914766012662120?l=musingsofaprogrammingaddict.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/MusingsOfAProgrammingAddict/~4/0-SqYfBn2nQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/MusingsOfAProgrammingAddict/~3/0-SqYfBn2nQ/article-on-bean-validation-api.html</link><author>noreply@blogger.com (Gunnar Morling)</author><thr:total>3</thr:total><feedburner:origLink>http://musingsofaprogrammingaddict.blogspot.com/2009/11/article-on-bean-validation-api.html</feedburner:origLink></item></channel></rss>

