<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ceres Logic :: Blog &#187; jpa</title>
	<atom:link href="http://www.cereslogic.com/pages/tag/jpa/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cereslogic.com/pages</link>
	<description>Mobile and Web App Development</description>
	<lastBuildDate>Tue, 23 Aug 2011 14:45:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Clearing Hibernate Second-Level Caches</title>
		<link>http://www.cereslogic.com/pages/2008/10/09/clearing-hibernate-second-level-caches/</link>
		<comments>http://www.cereslogic.com/pages/2008/10/09/clearing-hibernate-second-level-caches/#comments</comments>
		<pubDate>Thu, 09 Oct 2008 10:03:00 +0000</pubDate>
		<dc:creator>mdesjardins</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jpa]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/?p=34</guid>
		<description><![CDATA[Recently, I wanted to be able to clear out all of the Hibernate caches via JBoss&#8217;s JMX console. I could have taken the easy way out; we&#8217;re using EHCache, so it could have been as simple as calling CacheManager.clearAll(). However, that would have tied me to a specific cache provider. We&#8217;re still evaluating switching to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://mikedesjardins.us/blog/uploaded_images/chalkboards-1-FolkeB-735126.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://mikedesjardins.us/blog/uploaded_images/chalkboards-1-FolkeB-735124.jpg" border="0" alt="" /></a>Recently, I wanted to be able to clear out all of the Hibernate caches via JBoss&#8217;s JMX console.  I could have taken the easy way out; we&#8217;re using EHCache, so it could have been as simple as calling <span style="font-style: italic;">CacheManager.clearAll()</span>.  However, that would have tied me to a specific cache provider.  We&#8217;re still evaluating switching to other cache providers.  Ideally, my solution would not be dependent on a specific cache implementation.</p>
<p>Hibernate&#8217;s API does provide a simple way to clear specific caches, but does not provide any method for clearing out all of them.  Writing your own is fairly straightforward.  First, you obtain all of the entity and collection metadata from the session factory.  Next you iterate over the entities, and if the object is cached, you clear out all of the caches associated with the persisted class or collection.  Here&#8217;s the code:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  @PersistenceContext
  <span style="color: #000000; font-weight: bold;">private</span> EntityManager em<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> clearHibernateCache<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    Session s <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Session<span style="color: #009900;">&#41;</span>em.<span style="color: #006633;">getDelegate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    SessionFactory sf <span style="color: #339933;">=</span> s.<span style="color: #006633;">getSessionFactory</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    Map<span style="color: #339933;">&lt;</span>string,EntityPersister<span style="color: #339933;">&gt;</span> classMetadata <span style="color: #339933;">=</span> sf.<span style="color: #006633;">getAllClassMetadata</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>EntityPersister ep <span style="color: #339933;">:</span> classMetadata.<span style="color: #006633;">values</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>ep.<span style="color: #006633;">hasCache</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        sf.<span style="color: #006633;">evictEntity</span><span style="color: #009900;">&#40;</span>ep.<span style="color: #006633;">getCache</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getRegionName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    Map<span style="color: #339933;">&lt;</span>string,AbstractCollectionPersister<span style="color: #339933;">&gt;</span> collMetadata <span style="color: #339933;">=</span> sf.<span style="color: #006633;">getAllCollectionMetadata</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>AbstractCollectionPersister acp <span style="color: #339933;">:</span> collMetadata.<span style="color: #006633;">values</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>acp.<span style="color: #006633;">hasCache</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        sf.<span style="color: #006633;">evictCollection</span><span style="color: #009900;">&#40;</span>acp.<span style="color: #006633;">getCache</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getRegionName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">return</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now, if we decide to switch to a different cache provider, this code will not need to be re-written.  Hopefully we won&#8217;t ever change to a different JPA implementaion.  <img src='http://www.cereslogic.com/pages/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><span style="font-style: italic;">Photo Credit: </span><a style="font-style: italic;" href="http://flickr.com/people/24337020@N07/">FolkeB</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cereslogic.com/pages/2008/10/09/clearing-hibernate-second-level-caches/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hibernate Criteria Subqueries: Exists</title>
		<link>http://www.cereslogic.com/pages/2008/09/22/hibernate-criteria-subqueries-exists/</link>
		<comments>http://www.cereslogic.com/pages/2008/09/22/hibernate-criteria-subqueries-exists/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 15:00:00 +0000</pubDate>
		<dc:creator>mdesjardins</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[pizzashop]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/?p=33</guid>
		<description><![CDATA[NOTE: Apologies for the recent blogging hiatus. I just started a new job and haven&#8217;t had a lot of time to devote to this blog lately! While working on a recent project, I came into a situation where I needed to do an &#8220;exists&#8221; query, using a Criteria-style query. The online documentation for this feature [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://mikedesjardins.us/blog/uploaded_images/national-pizza-shop-718025.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 169px; height: 210px;" src="http://mikedesjardins.us/blog/uploaded_images/national-pizza-shop-718008.jpg" border="0" alt="" /></a><span style="font-style: italic;">NOTE: Apologies for the recent blogging hiatus.  I just started a new job and haven&#8217;t had a lot of time to devote to this blog lately!</span></p>
<p>While working on a recent project, I came into a situation where I needed to do an &#8220;exists&#8221; query, using a Criteria-style query.  The online documentation for this feature is a little sparse, so I thought I&#8217;d share what I did.</p>
<p><span style="font-weight: bold;">The Pizza-shop Data Model (Again)</span></p>
<div style="text-align: left;">I keep reusing a data model for a Pizza shop in my posts, and this post will be no different.  This data model first appeared in my <a href="http://mikedesjardins.us/blog/2008/01/new-jpa-tutorial-pizza-shop.html">JPA mapping tutorial</a>.  Here&#8217;s an ERD of the model again:</div>
<p><a href="http://mikedesjardins.us/blog/uploaded_images/pizza-erd-737223.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://mikedesjardins.us/blog/uploaded_images/pizza-erd-737223.jpg" border="0" alt="" /></a><span style="font-weight: bold;">Find me Orders with Small Pizzas!</span><br />
Given this model, what if we needed to find each order that contained a small pizza?  Suppose your database had the following data:</p>
<p><a href="http://mikedesjardins.us/blog/uploaded_images/table-752077.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://mikedesjardins.us/blog/uploaded_images/table-752035.jpg" border="0" alt="" /></a><br />
As with <a href="http://mikedesjardins.us/blog/2008/01/new-jpa-tutorial-pizza-shop.html">my earlier posting</a>, the object model has a PizzaOrder class that contains a Set of Pizza objects which correspond to each customer order.  Your first inclination might be to do a criteria-within-a-criteria, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Criteria criteria <span style="color: #339933;">=</span> Criteria.<span style="color: #006633;">forClass</span><span style="color: #009900;">&#40;</span>PizzaOrder.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
criteria.<span style="color: #006633;">createCriteria</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;pizza&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;pizza_size_id&quot;</span>,<span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003399;">List</span>
 ordersWithOneSmallPizza <span style="color: #339933;">=</span> criteria.<span style="color: #006633;">list</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>You&#8217;d be in for a bit of a surprise, though.  While you might expect only two Pizza orders to be returned (namely, orders #1 and #2), you&#8217;ll actually have three orders in the result set; because order #2 has two small pizzas in it, order #2 will appear twice in your results!</p>
<p>The reason why this happens is pretty simple, and it becomes clear if you enable Hibernate&#8217;s SQL output feature.  To locate all of the pizza orders which contain a small pizza, Hibernate needs to do an inner join to the PIZZA table.  This is true regardless of whether you&#8217;ve mapped the Pizza objects to be fetched lazily; the join is required because of your query criteria, not because of your mappings.  <span style="font-style: italic;">Note: it&#8217;d be really nice if Hibernate were clever enough to identify from the result set that it had duplicate PIZZA_ORDER records, and build the Set of Pizza objects accordingly, but I suspect that this would be a very difficult thing to do, so I&#8217;m not holding my breath.</span></p>
<p><span style="font-weight: bold;">The Right Way to Do It</span><br />
What you&#8217;re really trying to do is to obtain all Pizza Orders where an associated small pizza exists.  In other words, the SQL query that you&#8217;re trying to emulate is</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span>
  <span style="color: #993333; font-weight: bold;">FROM</span> PIZZA_ORDER
 <span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #cc66cc;">1</span>
                 <span style="color: #993333; font-weight: bold;">FROM</span> PIZZA
                <span style="color: #993333; font-weight: bold;">WHERE</span> PIZZA<span style="color: #66cc66;">.</span>pizza_size_id <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>
                  <span style="color: #993333; font-weight: bold;">AND</span> PIZZA<span style="color: #66cc66;">.</span>pizza_order_id <span style="color: #66cc66;">=</span> PIZZA_ORDER<span style="color: #66cc66;">.</span>pizza_order_id<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>The way that you do that is by using an &#8220;exists&#8221; Subquery, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Criteria criteria <span style="color: #339933;">=</span> Criteria.<span style="color: #006633;">forClass</span><span style="color: #009900;">&#40;</span>PizzaOrder.<span style="color: #000000; font-weight: bold;">class</span>,<span style="color: #0000ff;">&quot;pizzaOrder&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
DetachedCriteria sizeCriteria <span style="color: #339933;">=</span> DetachedCriteria.<span style="color: #006633;">forClass</span><span style="color: #009900;">&#40;</span>Pizza.<span style="color: #000000; font-weight: bold;">class</span>,<span style="color: #0000ff;">&quot;pizza&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
sizeCriteria.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;pizza_size_id&quot;</span>,<span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
sizeCriteria.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>Property.<span style="color: #006633;">forName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;pizza.pizza_order_id&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">eqProperty</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;pizzaOrder.pizza_order_id&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
criteria.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>Subqueries.<span style="color: #006633;">exists</span><span style="color: #009900;">&#40;</span>sizeCriteria.<span style="color: #006633;">setProjection</span><span style="color: #009900;">&#40;</span>Projections.<span style="color: #006633;">property</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;pizza.id&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
List<span style="color: #339933;">&lt;</span>pizzaOrder<span style="color: #339933;">&gt;</span> ordersWithOneSmallPizza <span style="color: #339933;">=</span> criteria.<span style="color: #006633;">list</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>And <span style="font-style: italic;">voila</span>, the result will contain two PizzaOrders!<br />
<span style="font-style: italic;">Photo Credit: </span><a href="http://flickr.com/people/squeakymarmot/"><span style="font-style: italic;">Squeaky Marmot</span></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cereslogic.com/pages/2008/09/22/hibernate-criteria-subqueries-exists/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hibernate Tools: Tips for Reverse Engineering at the Command Line</title>
		<link>http://www.cereslogic.com/pages/2008/08/05/hibernate-tools-tips-for-reverse/</link>
		<comments>http://www.cereslogic.com/pages/2008/08/05/hibernate-tools-tips-for-reverse/#comments</comments>
		<pubDate>Tue, 05 Aug 2008 16:24:00 +0000</pubDate>
		<dc:creator>mdesjardins</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/?p=32</guid>
		<description><![CDATA[One of the ancillary projects of the Hibernate framework is the Hibernate Tools toolset. Using Hibernate Tools, you can automatically generate your mapping files (or, if you prefer, JPA annotations), POJOs, and DDL from your database schema. I&#8217;ve been enamored with the &#8220;Convention over Configuration&#8221; web frameworks lately (e.g., Grails, Django), and wondered how hard [...]]]></description>
			<content:encoded><![CDATA[<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mikedesjardins.us/blog/uploaded_images/tools-geishaboy500-716138.jpg"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://mikedesjardins.us/blog/uploaded_images/tools-geishaboy500-716103.jpg" alt="" border="0"></a>One of the ancillary projects of the Hibernate framework is the <a href="http://www.hibernate.org/255.html">Hibernate Tools</a> toolset.  Using Hibernate Tools, you can automatically generate your mapping files (or, if you prefer, JPA annotations), POJOs, and DDL from your database schema.</p>
<p>I&#8217;ve been enamored with the &#8220;Convention over Configuration&#8221; web frameworks lately (e.g., Grails, Django), and wondered how hard it&#8217;d be to reproduce some of their magic ORM functionality using Hibernate Tools.  I&#8217;ve concluded that I&#8217;ve still got a <font style="font-weight: bold;">long</font> ways to go, but that I might have some worthwhile tips to share in the meantime.</p>
<p>My progress has been impeded a bit because the documentation for Hibernate Tools is pretty weak.  Hibernate Tools was really generated with Eclipse users in mind.  A large portion of the documentation is devoted to explaining how to use the IDE.  I&#8217;m not using Eclipse, and I intend to use the tools at the command-line, and command-line use really isn&#8217;t targeted.</p>
<p><font style="font-weight: bold;">0.) Get the tools and dependencies.</font><br />I&#8217;m still in the dark ages &#8211; I use ant instead of maven for builds, and need to track down jar dependencies the old fashioned way.  In addition to the usual Hibernate jars, you&#8217;ll also need <a href="http://www.hibernate.org/30.html">hibernate-tools</a>, <a href="http://freemarker.sourceforge.net/">freemarker</a>, and <a href="http://jtidy.sourceforge.net/download.html">jtidy</a>.</p>
<p><font style="font-weight: bold;"><br />
1.) Setup an Ant task</font><br />This is pretty straightforward, and it is explained fairly well in the documentation.  First, define yourself a Hibernate Tools task.  Mine looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;taskdef</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;hibernatetool&quot;</span> <span style="color: #000066;">classname</span>=<span style="color: #ff0000;">&quot;org.hibernate.tool.ant.HibernateToolTask&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;classpath<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">refid</span>=<span style="color: #ff0000;">&quot;hibernate.libs&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">refid</span>=<span style="color: #ff0000;">&quot;hibernatetools.libs&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">refid</span>=<span style="color: #ff0000;">&quot;app.libs&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">refid</span>=<span style="color: #ff0000;">&quot;compile.libs&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pathelement</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;${build}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pathelement</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;${basedir}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/classpath<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/taskdef<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Next, create a task that uses our new definition.  We&#8217;re going to be creating the mapping files and POJOs in this example.  It will look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;gen_hibernate&quot;</span> <span style="color: #000066;">depends</span>=<span style="color: #ff0000;">&quot;compile&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;delete</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${genhbm}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mkdir</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${genhbm}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hibernatetool<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jdbcconfiguration</span></span>
<span style="color: #009900;">        <span style="color: #000066;">configurationfile</span>=<span style="color: #ff0000;">&quot;${src}/hibernate-connection.cfg.xml&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">revengfile</span>=<span style="color: #ff0000;">&quot;hibernate.reveng.xml&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">packagename</span>=<span style="color: #ff0000;">&quot;us.mikedesjardins.data&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">detectmanytomany</span>=<span style="color: #ff0000;">&quot;true&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">detectoptimisticlock</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hbm2hbmxml</span> <span style="color: #000066;">destdir</span>=<span style="color: #ff0000;">&quot;${genhbm}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hbm2java</span> <span style="color: #000066;">destdir</span>=<span style="color: #ff0000;">&quot;${genhbm}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">key</span>=<span style="color: #ff0000;">&quot;jdk5&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">key</span>=<span style="color: #ff0000;">&quot;ejb3&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hbm2java<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hibernatetool<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>You&#8217;ll note that I&#8217;ve created a hibernate configuration file above which only contains connection information.  This is because I ran into problems when I tried to use a hibernate configuration with cache configuration elements in it.  You&#8217;ll also note a reference to a file called hibernate.reveng.xml.  This file controls various aspects of the reverse engineering process.  Mine is very simple &#8211; I&#8217;m working with MS SQL Server, and I don&#8217;t want it to include any of the system tables which begin with the prefix sys:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hibernate-reverse-engineering<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #808080; font-style: italic;">&lt;!-- Eliminate system tables  --&gt;</span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;table-filter</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;sys.*&quot;</span> <span style="color: #000066;">exclude</span>=<span style="color: #ff0000;">&quot;true&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hibernate-reverse-engineering<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>That should be all that you need to do to get started.  When you run this ant target, your domain object POJOs and Mappings should end up in the ${genhbm} directory.</p>
<p><font style="font-weight: bold;">2.) First Problem &#8211; Table Names</font><br />Let&#8217;s say you&#8217;re in a company that prefixes most of it&#8217;s tables with something silly, like &#8220;tb_&#8221;.  In that case, Hibernate tools will happily create all kinds of POJOs for you named TbAccount, TbAddress, etc.  This is probably not what you want.  Fortunately, Hibernate tools let you provide your own &#8220;Reverse Engineering Strategy&#8221; class to deal with situations just like this.</p>
<p>First, update your build target in Ant to include a reference to your strategy class as an attribute of the jdbcconfiguration element:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;gen_hibernate&quot;</span> <span style="color: #000066;">depends</span>=<span style="color: #ff0000;">&quot;compile&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;delete</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${genhbm}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mkdir</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${genhbm}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hibernatetool<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jdbcconfiguration</span></span>
<span style="color: #009900;">        <span style="color: #000066;">configurationfile</span>=<span style="color: #ff0000;">&quot;${src}/hibernate-connection.cfg.xml&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">revengfile</span>=<span style="color: #ff0000;">&quot;hibernate.reveng.xml&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">packagename</span>=<span style="color: #ff0000;">&quot;us.mikedesjardins.data&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">detectmanytomany</span>=<span style="color: #ff0000;">&quot;true&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">detectoptimisticlock</span>=<span style="color: #ff0000;">&quot;true&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">reversestrategy</span>=<span style="color: #ff0000;">&quot;us.mikedesjardins.hibernate.CustomReverseEngineeringStrategy&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hbm2hbmxml</span> <span style="color: #000066;">destdir</span>=<span style="color: #ff0000;">&quot;${genhbm}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hbm2java</span> <span style="color: #000066;">destdir</span>=<span style="color: #ff0000;">&quot;${genhbm}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">key</span>=<span style="color: #ff0000;">&quot;jdk5&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">key</span>=<span style="color: #ff0000;">&quot;ejb3&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hbm2java<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hibernatetool<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Next, we&#8217;ll need to create the strategy class.  The documentation recommends that you extend the <font style="font-weight: bold;">DelegatingReverseEngineeringStrategy</font> class to do this, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">us.mikedesjardins.hibernate</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.hibernate.cfg.reveng.DelegatingReverseEngineeringStrategy</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.hibernate.cfg.reveng.ReverseEngineeringStrategy</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CustomReverseEngineeringStrategy <span style="color: #000000; font-weight: bold;">extends</span> DelegatingReverseEngineeringStrategy <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> CustomReverseEngineeringStrategy<span style="color: #009900;">&#40;</span>ReverseEngineeringStrategy delegate <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>delegate<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Unfortunately, I was unable to find any JavaDoc documentation for the Hibernate Tools classes, so I had to do a bit of trial-and-error.  It turns out there is a method called tableToClassName that can be overridden.  This class accepts a TableIdentifier as its input parameter, and returns the class name in a String.  Thus, to remove the tb_ from the class, we could do something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> tableToClassName<span style="color: #009900;">&#40;</span>TableIdentifier tableIdentifier<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003399;">String</span> packageName <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;us.mikedesjardins.data&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #003399;">String</span> className <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">tableToClassName</span><span style="color: #009900;">&#40;</span>tableIdentifier<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>className.<span style="color: #006633;">startsWith</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Tb&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    className <span style="color: #339933;">=</span> className.<span style="color: #006633;">substring</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000000; font-weight: bold;">return</span> className<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Compile your CustomReverseEngineeringStrategy class, make sure it&#8217;s on the hibernatetools task definition&#8217;s classpath, and re-run the task.  Voila!  The Tb&#8217;s are gone!</p>
<p>There&#8217;s a similar method for column names named <font style="font-weight: bold;">columnToPropertyName</font> that handles naming your persisted class&#8217;s member variables.  In my current project, the primary key columns are named the same as the table name, with &#8220;_id&#8221; appended to the end.  However, in the object model, we like to just name the primary key property &#8220;id&#8221; to simplify the creation of generic DAOs.  I use the columnToPropertyName method for this.</p>
<p><font style="font-weight: bold;">2.) Next Problem &#8211; The Generated POJOs need tweaking.</font><br />Perhaps the code that Hibernate generates is not to your liking.  Maybe you work with standards-compliance-nazis who want a copyright header at the top of each class file.  Or maybe all of your persisted objects implement the same interface for use with generic DAOs.</p>
<p>Under the covers, Hibernate uses <a href="http://freemarker.sourceforge.net/">freemarker</a> to generate POJOs and mapping files.  The templates that it uses can be edited to your liking, but doing it is not very straightforward.</p>
<p>First, unzip the hibernate tools jar into a temporary directory.  Once unzipped, you&#8217;ll find a directory named pojo.  This directory contains all of the templates used for POJO generation.  Copy that directory into your build area and name it something like hib_templates.</p>
<p>The hbm2java task is actually just an alias for another hibernate tools target called hbmtemplate.  With hbmtemplate, you can configure the location of the source templates.  So we&#8217;ll remove the hbm2java task from the gen_hibernate target, and replace it with an equivalent hbmtemplate task:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;gen_hibernate&quot;</span> <span style="color: #000066;">depends</span>=<span style="color: #ff0000;">&quot;compile&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;delete</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${genhbm}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mkdir</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${genhbm}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hibernatetool<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jdbcconfiguration</span></span>
<span style="color: #009900;">        <span style="color: #000066;">configurationfile</span>=<span style="color: #ff0000;">&quot;${src}/hibernate-connection.cfg.xml&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">revengfile</span>=<span style="color: #ff0000;">&quot;hibernate.reveng.xml&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">packagename</span>=<span style="color: #ff0000;">&quot;us.mikedesjardins.data&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">detectmanytomany</span>=<span style="color: #ff0000;">&quot;true&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">detectoptimisticlock</span>=<span style="color: #ff0000;">&quot;true&quot;</span></span>
<span style="color: #009900;">        <span style="color: #000066;">reversestrategy</span>=<span style="color: #ff0000;">&quot;us.mikedesjardins.hibernate.CustomReverseEngineeringStrategy&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hbm2hbmxml</span> <span style="color: #000066;">destdir</span>=<span style="color: #ff0000;">&quot;${genhbm}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hbmtemplate</span> <span style="color: #000066;">templateprefix</span>=<span style="color: #ff0000;">&quot;pojo/&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">destdir</span>=<span style="color: #ff0000;">&quot;${genhbm}&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">template</span>=<span style="color: #ff0000;">&quot;hib_templates/Pojo.ftl&quot;</span></span>
<span style="color: #009900;">              <span style="color: #000066;">filepattern</span>=<span style="color: #ff0000;">&quot;{package-name}/{class-name}.java&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">key</span>=<span style="color: #ff0000;">&quot;jdk5&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;true&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">key</span>=<span style="color: #ff0000;">&quot;ejb3&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hbmtemplate<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hibernatetool<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Now that we&#8217;ve told hibernate tools where our template lives, we can edit it to our liking.  For example, if we want to add a copyright notice to the top of each generated POJO, we could do so thusly:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//</span>
<span style="color: #666666; font-style: italic;">// Copyright 2008 Big Amalgamated Mega Global Software Corp.  All Rights Reserved.</span>
<span style="color: #666666; font-style: italic;">//</span>
$<span style="color: #009900;">&#123;</span>pojo.<span style="color: #006633;">getPackageDeclaration</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span>
<span style="color: #666666; font-style: italic;">// Generated ${date} by Hibernate Tools ${version}</span>
&nbsp;
<span style="color: #339933;">&lt;</span>#assign classbody<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>#include <span style="color: #0000ff;">&quot;PojoTypeDeclaration.ftl&quot;</span><span style="color: #339933;">/&gt;;</span> <span style="color: #009900;">&#123;</span>
.
.
.
<span style="color: #009900;">&#40;</span>etc<span style="color: #009900;">&#41;</span></pre></div></div>

<p>Now that we&#8217;ve done this, we can create more templates that, e.g., generate empty DAO classes, automatically create derived classes, etc.</p>
<p>Hope that helps!</p>
<p><font style="font-style: italic;">Photo Credit: </font><a style="font-style: italic;" href="http://flickr.com/people/geishaboy500/">geishaboy500</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cereslogic.com/pages/2008/08/05/hibernate-tools-tips-for-reverse/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Twenty minutes with Hibernate Search; A Cheesy Example</title>
		<link>http://www.cereslogic.com/pages/2008/07/12/twenty-minutes-with-hibernate-search-a-cheesy-example/</link>
		<comments>http://www.cereslogic.com/pages/2008/07/12/twenty-minutes-with-hibernate-search-a-cheesy-example/#comments</comments>
		<pubDate>Sat, 12 Jul 2008 13:48:00 +0000</pubDate>
		<dc:creator>mdesjardins</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/?p=31</guid>
		<description><![CDATA[In a recent post, I showed a trick for determining which users in a system are running a long-running query. One commenter suggested that using a full-text search system made a lot of sense in those situations, and I wholeheartedly agree. So I decided to devote a new post to Hibernate Search! In this example, [...]]]></description>
			<content:encoded><![CDATA[<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mikedesjardins.us/blog/uploaded_images/cheese-blog-719088.jpg"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://mikedesjardins.us/blog/uploaded_images/cheese-blog-719057.jpg" alt="" border="0" /></a>In a <a href="http://mikedesjardins.us/blog/2008/06/who-is-running-that-horrible-hibernate.html">recent post</a>, I showed a trick for determining which users in a system are running a long-running query.  One commenter suggested that using a full-text search system made a lot of sense in those situations, and I wholeheartedly agree. So I decided to devote a new post to <a href="http://www.hibernate.org/410.html">Hibernate Search</a>!</p>
<p>In this example, I provide a live, <a href="http://mikedesjardins.us/cheese/search">online interactive search</a> of an online cheese database, and you can download the example (more on that at the end of the post).</p>
<p><span style="font-weight: bold;">Step One &#8211; The Test Data</span><br />I spent the most time on this project was creating test data for the example program.  I headed over to <a href="http://freebase.com/">Freebase</a> to see what was available for data sets.  Among lots of other things, they have a free database of <a href="http://www.freebase.com/view/food/cheese">cheese</a>.  First, I downloaded the data in TSV format, dumped it into a raw table, and massaged it into a relational, normalized schema.  I ended up with this when I was done:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mikedesjardins.us/blog/uploaded_images/cheese-search-erd-785039.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://mikedesjardins.us/blog/uploaded_images/cheese-search-erd-785035.jpg" alt="" border="0" /></a>So, a CHEESE can have only one ORIGIN (a country or region where the cheese is made), is made from one-to-many types of MILK, and may have zero-to-many TEXTURES associated with it.</p>
<p><span style="font-weight: bold;">Step Two &#8211; Build the Domain Model</span><br />The domain model for this system is very simple.  Each Cheese class has an Origin, and a set of Milk and Textures:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Entity</span> @Table<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;MILK&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Milk <span style="color: #009900;">&#123;</span>
  @Id @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;milk_id&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> id<span style="color: #339933;">;</span>
&nbsp;
  @Basic @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;name&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> name<span style="color: #339933;">;</span>
&nbsp;
  @Version @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;version&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> version<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Accessors omitted</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Entity</span> @Table<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;ORIGIN&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Origin <span style="color: #009900;">&#123;</span>
  @Id @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;origin_id&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> id<span style="color: #339933;">;</span>
&nbsp;
  @Basic @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;name&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> name<span style="color: #339933;">;</span>
&nbsp;
  @Version @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;version&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> version<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Accessors omitted</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Entity</span> @Table<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;TEXTURE&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Texture <span style="color: #009900;">&#123;</span>
  @Id @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;texture_id&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> id<span style="color: #339933;">;</span>
&nbsp;
  @Basic @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;description&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> description<span style="color: #339933;">;</span>
&nbsp;
  @Version @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;version&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> version<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Accessors omitted</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Entity</span> @Table<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;CHEESE&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Cheese <span style="color: #009900;">&#123;</span>
  @Id @GeneratedValue<span style="color: #009900;">&#40;</span>strategy<span style="color: #339933;">=</span>GenerationType.<span style="color: #006633;">IDENTITY</span><span style="color: #009900;">&#41;</span>
  @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;cheese_id&quot;</span>,nullable<span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">false</span>,unique<span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> id<span style="color: #339933;">;</span>
&nbsp;
  @Basic @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;name&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> name<span style="color: #339933;">;</span>
&nbsp;
  @ManyToOne<span style="color: #009900;">&#40;</span>cascade<span style="color: #339933;">=</span><span style="color: #009900;">&#123;</span>CascadeType.<span style="color: #006633;">ALL</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
  @JoinColumn<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;origin_id&quot;</span>,nullable<span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> Origin origin<span style="color: #339933;">;</span>
&nbsp;
  @ManyToMany<span style="color: #009900;">&#40;</span>cascade<span style="color: #339933;">=</span><span style="color: #009900;">&#123;</span>CascadeType.<span style="color: #006633;">PERSIST</span>,CascadeType.<span style="color: #006633;">MERGE</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
  @JoinTable<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;CHEESE_MILK_MAP&quot;</span>,
             joinColumns<span style="color: #339933;">=</span>@JoinColumn<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;cheese_id&quot;</span><span style="color: #009900;">&#41;</span>,
             inverseJoinColumns<span style="color: #339933;">=</span>@JoinColumn<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;milk_id&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> Set<span style="color: #339933;">&lt;</span>milk<span style="color: #339933;">&gt;</span> milks <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HashSet<span style="color: #339933;">&lt;</span>milk<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  @ManyToMany<span style="color: #009900;">&#40;</span>cascade<span style="color: #339933;">=</span><span style="color: #009900;">&#123;</span>CascadeType.<span style="color: #006633;">PERSIST</span>,CascadeType.<span style="color: #006633;">MERGE</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
  @JoinTable<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;CHEESE_TEXTURE_MAP&quot;</span>,
             joinColumns<span style="color: #339933;">=</span>@JoinColumn<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;cheese_id&quot;</span><span style="color: #009900;">&#41;</span>,
             inverseJoinColumns<span style="color: #339933;">=</span>@JoinColumn<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;texture_id&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> Set<span style="color: #339933;">&lt;</span>texture<span style="color: #339933;">&gt;</span> textures <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HashSet<span style="color: #339933;">&lt;</span>texture<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  @Version @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;version&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> version<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Accessors omitted</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><span style="font-weight: bold;">Step Three &#8211; Add Search Annotations and Configure Lucene</span><br />Behind the scenes, Hibernate Search uses the <a href="http://lucene.apache.org/">Apache Lucene</a> search engine to do its indexing. In short, it maintains a mapping of object IDs to search terms in an external file, and updates the file when objects are added, updated, or deleted.  To start using Hibernate Search, you&#8217;ll need to configure the location of these index files, as well as a search directory provider (we&#8217;ll just use the default).  This is done in your Hibernate properties file, or (if you use JPA, like me), in persistence.xml:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;hibernate.search.default.directory_provider&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;org.hibernate.search.store.FSDirectoryProvider&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;hibernate.search.default.indexBase&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;/var/lucene/cheese-indexes&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>Next, you need to indicate to Lucene which classes need to be indexed.  You also need to indicate which data fields 1.) contain the document ID, and 2.) contain relevant search text.  In our example, we only need to index the Cheese objects.  We want to allow users to search on cheese name, milk name, origin, and texture.</p>
<p>First, we indicate that we want to index the Cheese objects by applying the <span style="font-weight: bold;">@Indexed</span> annotation to the class, and we elect to use the Id field to identify the Cheese objects to Lucene by applying a <span style="font-weight: bold;">@DocumentId</span> annotation to it.  Next, we indicate that the cheese name contains searchable text by adding the <span style="font-weight: bold;">@Field(index=Index.TOKENIZED, store=Store.NO)</span> annotation to it.  The annotation parameters are informing Hibernate Search to use Lucene&#8217;s default tokenizer to summarize the text, and not to store a copy of the document content.</p>
<p>We also want to allow users to search on Origin, Milk Name, and Texture.  This text is not contained within the Cheese object, instead they&#8217;re in related object.  So we need to add the <span style="font-weight: bold;">@IndexEmbedded</span> annotation to the member variables in the Cheese class that refer to the objects which contain the searchable text, and we also need to add the <span style="font-weight: bold;">@Field(index=Index.TOKENIZED, store=Store.NO)</span> annotation to the Milk, Origin, and Texture classes to indicate which fields are searchable.</p>
<p>When you&#8217;re done, the modified domain classes will look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Entity</span> @Table<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;MILK&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Milk <span style="color: #009900;">&#123;</span>
  @Id @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;milk_id&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> id<span style="color: #339933;">;</span>
&nbsp;
  @<span style="color: #003399;">Field</span><span style="color: #009900;">&#40;</span>index<span style="color: #339933;">=</span>Index.<span style="color: #006633;">TOKENIZED</span><span style="color: #009900;">&#41;</span>
  @Basic @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;name&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> name<span style="color: #339933;">;</span>
&nbsp;
  @Version @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;version&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> version<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Accessors omitted</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Entity</span> @Table<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;ORIGIN&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Origin <span style="color: #009900;">&#123;</span>
  @Id @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;origin_id&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> id<span style="color: #339933;">;</span>
&nbsp;
  @<span style="color: #003399;">Field</span><span style="color: #009900;">&#40;</span>index<span style="color: #339933;">=</span>Index.<span style="color: #006633;">TOKENIZED</span><span style="color: #009900;">&#41;</span>
  @Basic @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;name&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> name<span style="color: #339933;">;</span>
&nbsp;
  @Version @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;version&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> version<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Accessors omitted</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Entity</span> @Table<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;TEXTURE&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Texture <span style="color: #009900;">&#123;</span>
  @Id @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;texture_id&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> id<span style="color: #339933;">;</span>
&nbsp;
  @<span style="color: #003399;">Field</span><span style="color: #009900;">&#40;</span>index<span style="color: #339933;">=</span>Index.<span style="color: #006633;">TOKENIZED</span><span style="color: #009900;">&#41;</span>
  @Basic @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;description&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> description<span style="color: #339933;">;</span>
&nbsp;
  @Version @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;version&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> version<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Accessors omitted</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@Indexed
@<span style="color: #003399;">Entity</span> @Table<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;CHEESE&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Cheese <span style="color: #009900;">&#123;</span>
  @DocumentId
  @Id @GeneratedValue<span style="color: #009900;">&#40;</span>strategy<span style="color: #339933;">=</span>GenerationType.<span style="color: #006633;">IDENTITY</span><span style="color: #009900;">&#41;</span>
  @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;cheese_id&quot;</span>,nullable<span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">false</span>,unique<span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> id<span style="color: #339933;">;</span>
&nbsp;
  @Basic @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;name&quot;</span><span style="color: #009900;">&#41;</span>
  @<span style="color: #003399;">Field</span><span style="color: #009900;">&#40;</span>index<span style="color: #339933;">=</span>Index.<span style="color: #006633;">TOKENIZED</span>, store<span style="color: #339933;">=</span>Store.<span style="color: #006633;">NO</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> name<span style="color: #339933;">;</span>
&nbsp;
  @IndexedEmbedded
  @ManyToOne<span style="color: #009900;">&#40;</span>cascade<span style="color: #339933;">=</span><span style="color: #009900;">&#123;</span>CascadeType.<span style="color: #006633;">ALL</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
  @JoinColumn<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;origin_id&quot;</span>,nullable<span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> Origin origin<span style="color: #339933;">;</span>
&nbsp;
  @IndexedEmbedded
  @ManyToMany<span style="color: #009900;">&#40;</span>cascade<span style="color: #339933;">=</span><span style="color: #009900;">&#123;</span>CascadeType.<span style="color: #006633;">PERSIST</span>,CascadeType.<span style="color: #006633;">MERGE</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
  @JoinTable<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;CHEESE_MILK_MAP&quot;</span>,
             joinColumns<span style="color: #339933;">=</span>@JoinColumn<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;cheese_id&quot;</span><span style="color: #009900;">&#41;</span>,
             inverseJoinColumns<span style="color: #339933;">=</span>@JoinColumn<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;milk_id&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> Set<span style="color: #339933;">&lt;</span>milk<span style="color: #339933;">&gt;</span> milks <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HashSet<span style="color: #339933;">&lt;</span>milk<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  @IndexedEmbedded
  @ManyToMany<span style="color: #009900;">&#40;</span>cascade<span style="color: #339933;">=</span><span style="color: #009900;">&#123;</span>CascadeType.<span style="color: #006633;">PERSIST</span>,CascadeType.<span style="color: #006633;">MERGE</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
  @JoinTable<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;CHEESE_TEXTURE_MAP&quot;</span>,
             joinColumns<span style="color: #339933;">=</span>@JoinColumn<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;cheese_id&quot;</span><span style="color: #009900;">&#41;</span>,
             inverseJoinColumns<span style="color: #339933;">=</span>@JoinColumn<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;texture_id&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> Set<span style="color: #339933;">&lt;</span>texture<span style="color: #339933;">&gt;</span> textures <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HashSet<span style="color: #339933;">&lt;</span>texture<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  @Version @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;version&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> version<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Accessors omitted</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><span style="font-weight: bold;">Step Four &#8211; The Servlets</span><br />In this example, I didn&#8217;t want to rely on any web frameworks or even on JSPs, so I wrote a good old-fashioned servlet to exercise the search function.  No sane person would ever do it this way.   There are actually two servlets in the example &#8211; one for application initialization and one for the page itself.</p>
<p>The initialization servlet does the work of indexing all of the database data the first time through.  For our small data set, this takes less than a minute.  For larger data sets, it wouldn&#8217;t make sense to re-index everything every time you start the application.  The initialization code iterates over all of the Cheese objects ant tells the FullTextEntityManger to index it:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  Dao<span style="color: #339933;">&lt;</span>cheese<span style="color: #339933;">&gt;</span> dao <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CheeseDao<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  EntityManager em <span style="color: #339933;">=</span> dao.<span style="color: #006633;">getEntityManager</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  FullTextEntityManager fullTextEntityManager <span style="color: #339933;">=</span> Search.<span style="color: #006633;">createFullTextEntityManager</span><span style="color: #009900;">&#40;</span>em<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  List<span style="color: #339933;">&lt;</span>cheese<span style="color: #339933;">&gt;</span> cheeses <span style="color: #339933;">=</span> em.<span style="color: #006633;">createQuery</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;select c from Cheese as c&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getResultList</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Cheese cheese <span style="color: #339933;">:</span> cheeses<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    fullTextEntityManager.<span style="color: #006633;">index</span><span style="color: #009900;">&#40;</span>cheese<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The main page servlet has some code in the doPost method to perform the search based on the contents of the text form field.  That code looks like this (I&#8217;ve shortened it up a bit here by removing some error checking and HTML output):</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> doPost<span style="color: #009900;">&#40;</span>HttpServletRequest request,
                   HttpServletResponse response<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> ServletException, <span style="color: #003399;">IOException</span> <span style="color: #009900;">&#123;</span>
  response.<span style="color: #006633;">setContentType</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;text/html&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003399;">PrintWriter</span> out <span style="color: #339933;">=</span> response.<span style="color: #006633;">getWriter</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  emitHeader<span style="color: #009900;">&#40;</span>out<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #003399;">String</span> searchTerm <span style="color: #339933;">=</span> request.<span style="color: #006633;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;searchterm&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  EntityManager em <span style="color: #339933;">=</span> dao.<span style="color: #006633;">getEntityManager</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  FullTextEntityManager fullTextEntityManager <span style="color: #339933;">=</span>
    org.<span style="color: #006633;">hibernate</span>.<span style="color: #006633;">search</span>.<span style="color: #006633;">jpa</span>.<span style="color: #006633;">Search</span>.<span style="color: #006633;">createFullTextEntityManager</span><span style="color: #009900;">&#40;</span>em<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  MultiFieldQueryParser parser <span style="color: #339933;">=</span>
    <span style="color: #000000; font-weight: bold;">new</span> MultiFieldQueryParser<span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;name&quot;</span>,
                                            <span style="color: #0000ff;">&quot;origin.name&quot;</span>,
                                            <span style="color: #0000ff;">&quot;milks.name&quot;</span>,
                                            <span style="color: #0000ff;">&quot;textures.description&quot;</span><span style="color: #009900;">&#125;</span>,
                               <span style="color: #000000; font-weight: bold;">new</span> StandardAnalyzer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
    org.<span style="color: #006633;">apache</span>.<span style="color: #006633;">lucene</span>.<span style="color: #006633;">search</span>.<span style="color: #006633;">Query</span> query <span style="color: #339933;">=</span> parser.<span style="color: #006633;">parse</span><span style="color: #009900;">&#40;</span>searchTerm<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    javax.<span style="color: #006633;">persistence</span>.<span style="color: #006633;">Query</span> hibQuery <span style="color: #339933;">=</span>
      fullTextEntityManager.<span style="color: #006633;">createFullTextQuery</span><span style="color: #009900;">&#40;</span>query,Cheese.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    List<span style="color: #339933;">&lt;</span>cheese<span style="color: #339933;">&gt;</span> result <span style="color: #339933;">=</span> hibQuery.<span style="color: #006633;">getResultList</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    emitTable<span style="color: #009900;">&#40;</span>out,result<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">ParseException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    log.<span style="color: #006633;">error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Got a parse exception&quot;</span>, e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> ServletException<span style="color: #009900;">&#40;</span>e.<span style="color: #006633;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  emitFooter<span style="color: #009900;">&#40;</span>out<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  out.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>That&#8217;s all there is to it!  As you can see, setting up Hibernate Search is very simple.  Most of the effort for this project was spent creating the data and making the servlets work.</p>
<p><span style="font-weight: bold;">Enjoy the Finished Product</span><br />To see this less-than-world-changing application in action, visit it <a href="http://mikedesjardins.us/cheese/search">here</a>.  You can also <a href="http://mikedesjardins.us/cheese-search-1.0.tar.gz">download the whole eclipse project</a> and try it out for yourself.  It comes with SQL dumps suitable for MySQL and PostgreSQL, and it has been tested with both environments under Tomcat 5.5.</p>
<p><span style="font-style: italic;">Photo Credit: </span><a href="http://www.flickr.com/people/cuse/"><span style="font-style: italic;font-size:100%;" ><span class="RealName"><span class="fn n"><span class="given-name">Chris</span> <span class="family-name">Buecheler</span></span></span></span></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cereslogic.com/pages/2008/07/12/twenty-minutes-with-hibernate-search-a-cheesy-example/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Use Hibernate&#8217;s Custom Loaders to fake an aggregation view</title>
		<link>http://www.cereslogic.com/pages/2008/06/23/use-hibernates-custom-loaders-to-fake/</link>
		<comments>http://www.cereslogic.com/pages/2008/06/23/use-hibernates-custom-loaders-to-fake/#comments</comments>
		<pubDate>Mon, 23 Jun 2008 17:37:00 +0000</pubDate>
		<dc:creator>mdesjardins</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/2008/06/use-hibernates-custom-loaders-to-fake-an-aggregation-view/</guid>
		<description><![CDATA[Your ProblemYou have a data model with table that contains data you want to aggregate. For instance (returning to my venerable Pizza Shop example), let&#8217;s say you have a PRODUCT table that enumerates the items your pizza shops sells, and a LOCATION table that contains all of your retail locations: We also have a table [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-weight: bold;">Your Problem</span><br />You have a data model with table that contains data you want to aggregate.  For instance (returning to my venerable Pizza Shop example), let&#8217;s say you have a PRODUCT table that enumerates the items your pizza shops sells, and a LOCATION table that contains all of your retail locations:</p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mikedesjardins.us/blog/uploaded_images/blog-location-product-791817.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://mikedesjardins.us/blog/uploaded_images/blog-location-product-791813.png" alt="" border="0" /></a><br />We also have a table that contains the sum of all of the previous days&#8217; sales, broken down by PRODUCT and LOCATION:</p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mikedesjardins.us/blog/uploaded_images/blog-yesterday-sales-786534.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://mikedesjardins.us/blog/uploaded_images/blog-yesterday-sales-786525.png" alt="" border="0" /></a>This is all well and good, but we&#8217;ve been asked to create an Executive Dashboard for the President of the pizza chain, and she would like to see daily sales by product.  She is not interested in a breakdown by location.</p>
<p><span style="font-weight: bold;">We could tally it up client side&#8230;</span><br />What if we just loaded the entire table into the client, and iterated over the per-product results, and present that?  Unfortunately, ORM libraries are pretty stupid in situations like these, and will generate all kinds of expensive reads to the database when you try to solve the problem this way.  If you want to learn more about lazy loading, and why you shouldn&#8217;t iterate over a collection, check out my earlier post <a href="http://mikedesjardins.us/blog/2008/03/pizza-shop-2-totaling-jpa-order-use.html">here</a>.</p>
<p><span style="font-weight: bold;">We could just create a view in the Database&#8230;</span><br />We <span>could</span><span style="font-weight: bold;"> </span>just create a view, and aggregate the data there.  Then we can easily create a Hibernate mapping to that view.  The query for the view is simple:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">VIEW</span> sales_by_product_view <span style="color: #993333; font-weight: bold;">AS</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> product_id<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">SUM</span><span style="color: #66cc66;">&#40;</span>total_sales<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> total_sales
  <span style="color: #993333; font-weight: bold;">FROM</span> YESTERDAY_SALES
 <span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> product_id</pre></div></div>

<p>However, we are working with a tyrannical DBA.  She is not keen on proliferating views throughout our otherwise pristine schema every time the President has decided that the company needs a new widget for the executive dashboard application.</p>
<p><span style="font-weight: bold;">&#8230;or we could fake it with a custom loader</span><br />Instead, let&#8217;s create a Hibernate mapping that generates the same results as the view.  First, let&#8217;s create a simple POJO to contain the results:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">us.mikedesjardins</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SalesByProduct <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> id<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> productId<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">BigDecimal</span> sales<span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// accessors omitted</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The corresponding mapping file would look like this.  I re-used the product_id for the ID in this  example.  Note the loader element:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hibernate-mapping</span> <span style="color: #000066;">package</span>=<span style="color: #ff0000;">&quot;us.mikedesjardins&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;class</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;SalesByProduct&quot;</span></span>
<span style="color: #009900;">          <span style="color: #000066;">dynamic-insert</span>=<span style="color: #ff0000;">&quot;false&quot;</span></span>
<span style="color: #009900;">          <span style="color: #000066;">dynamic-update</span>=<span style="color: #ff0000;">&quot;false&quot;</span></span>
<span style="color: #009900;">          <span style="color: #000066;">mutable</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;id&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;int&quot;</span> <span style="color: #000066;">unsaved-value</span>=<span style="color: #ff0000;">&quot;null&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;column</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;__id&quot;</span> <span style="color: #000066;">sql-type</span>=<span style="color: #ff0000;">&quot;int identity&quot;</span> <span style="color: #000066;">not-null</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">unique</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;productId&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;int&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;column</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;__product_id&quot;</span> <span style="color: #000066;">not-null</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/property<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;sales&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;java.math.BigDecimal&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;column</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;__total_sales&quot;</span> <span style="color: #000066;">not-null</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/property<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;loader</span> <span style="color: #000066;">query-ref</span>=<span style="color: #ff0000;">&quot;salesByProductQuery&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;sql-query</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;salesByProductQuery&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;return</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;SalesByProduct&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #339933;">&lt;![CDATA[</span>
<span style="color: #339933;">    select product_id as __id</span>
<span style="color: #339933;">         , product_id as __product_id</span>
<span style="color: #339933;">         , sum(total_sales) as __total_sales</span>
<span style="color: #339933;">      from YESTERDAY_SALES</span>
<span style="color: #339933;">     where product_id = :product_id</span>
<span style="color: #339933;">    group by product_id</span>
<span style="color: #339933;">   ]]&gt;</span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/sql-query<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hibernate-mapping<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Note that you need to put a positional argument in the query, or Hibernate will get nasty about parsing it.  Hope that helps!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cereslogic.com/pages/2008/06/23/use-hibernates-custom-loaders-to-fake/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why you should not not use ORM</title>
		<link>http://www.cereslogic.com/pages/2008/06/16/why-you-should-not-not-use-orm/</link>
		<comments>http://www.cereslogic.com/pages/2008/06/16/why-you-should-not-not-use-orm/#comments</comments>
		<pubDate>Mon, 16 Jun 2008 23:32:00 +0000</pubDate>
		<dc:creator>mdesjardins</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/2008/06/why-you-should-not-not-use-orm/</guid>
		<description><![CDATA[Yesterday I read a blog post by Kenneth Downs entitled &#8220;Why I Do Not Use ORM&#8221; on his The Database Programmer blog. It wasn&#8217;t the first blog post with gripes about Object Relational Mapping, and it certainly won&#8217;t be the last. For me, this particular article highlighted a few misconceptions about why and how ORM [...]]]></description>
			<content:encoded><![CDATA[<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mikedesjardins.us/blog/uploaded_images/2522766037_44d8e2e709-731771.jpg"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://mikedesjardins.us/blog/uploaded_images/2522766037_44d8e2e709-731749.jpg" alt="" border="0" /></a>Yesterday I read a blog post by Kenneth Downs entitled &#8220;<a href="http://database-programmer.blogspot.com/2008/06/why-i-do-not-use-orm.html">Why I Do Not Use ORM</a>&#8221; on his <a href="http://database-programmer.blogspot.com/">The Database Programmer</a> blog.  It wasn&#8217;t the first blog post with gripes about Object Relational Mapping, and it certainly won&#8217;t be the last.  For me, this particular article highlighted a few misconceptions about why and how ORM should be used, and I thought I might chime in with my own perspective.</p>
<p><span style="font-weight: bold;">ORM is not a way to avoid SQL</span><br />The first thing that stood out for me was this quote:<br />
<blockquote>&#8220;The language SQL is the most widely supported, implemented, and    used way to connect to databases.  But since most of us have long    lists of complaints about the language, we end up writing abstraction    layers that make it easier for us to avoid coding SQL directly.&#8221;</p></blockquote>
<p>To his credit, the author wasn&#8217;t actually addressing ORM in this paragraph.  However, anyone writing business logic which interacts with a database, who is unable to write some basic SQL, is like a bull in a china shop; nothing good will come of it regardless of the tools and abstraction layers employed.</p>
<p><span style="font-weight: bold;">The Simple Example</span><br />The next example in the post shows how one would write a row to a database in only four lines of PHP code &#8211; it looks something like this (I removed the comments):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> getPostStartingWith<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;inp_&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$table_id</span> <span style="color: #339933;">=</span> myGetPostVarFunction<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table_id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>SQLX_Insert<span style="color: #009900;">&#40;</span><span style="color: #000088;">$table_id</span><span style="color: #339933;">,</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 myFrameworkErrorReporting<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>I don&#8217;t know PHP, but I think the code is reading every field in a posted form that starts with inp_, generates an insert statement straight from the ID&#8217;s on the form fields, and writes an insert statement with the results.</p>
<p>Perhaps it&#8217;s unfair to criticize this code because &#8220;it&#8217;s just a simple example,&#8221; but if this code is being held up as an example of how short and simple non-ORM code can be, one does have to wonder
<ul>
<li>When the database schema changes, does the HTML need to be updated so that the form fields match the database schema?</li>
<li>Where are the transactions?  What if I need to insert into several tables and roll back the transaction if one fails?</li>
<li>Does the handy SQLX_insert method prevent SQL injection attacks?</li>
</ul>
<p>He goes on to say that this task is made even easier by <a href="http://database-programmer.blogspot.com/2008/06/using-data-dictionary.html">using a data dictionary</a> to generate the SQL.  After reading the &#8220;Using a Data Dictionary&#8221; article, one has to wonder whether or not the author realizes that it is a very crude form of ORM.</p>
<p><span style="font-weight: bold;">What about Business Logic?</span><br />Kenneth Downs tries to head-off any arguments about business logic before they come up, knowing that ORM evangelists will argue that the domain objects can encapsulate essential business logic for the application.  His response?<br />
<blockquote>&#8220;The SQLX_Insert()    routine can call out to functions (fast) or objects     (much slower) that massage data before and after the    insert operation.  I will be demonstrating some of these    techniques in future essays, but of course the best     permforming and safest method is to use triggers.&#8221;</p></blockquote>
<p>For me, this sounds alarm bells.  Triggers slow down transactions.  Triggers are in your database, which is often your system&#8217;s biggest bottleneck.  Triggers silently do things behind your back without telling you.  Triggers change databases from vast, efficient places to store relational data, into a lumbering behemoth interpreting procedural code inside big iron.</p>
<p>Conversely, business logic that can be easily distributed across many smaller web servers scales horizontally.  The domain layer is a fantastic place to embed simple data massaging &#8211; sadly, I often see a pile of persistent entities with getters and setters that don&#8217;t do anything.</p>
<p><span style="font-weight: bold;">Counter Example: The Disaster Scenario</span><br />Lastly, Ken (can I call him that?  What is the ettiquite for this sort of thing, anyway?) shows an example of a piece of code that is likely to cause hundreds of unneeded reads to the database in an untuned ORM-based system.  I don&#8217;t dispute this; in fact, I <a href="http://mikedesjardins.us/blog/2008/03/pizza-shop-2-totaling-jpa-order-use.html">posted</a> about an almost identical nightmare scenario myself a while ago.</p>
<p>For this, I go back to my &#8220;bull in a china shop&#8221; analogy.  Programmers can write horrible code in any language, with any tool.  Layers of abstraction are a double-edged sword, because you need to understand what they are doing for you.  But it&#8217;s not the tool&#8217;s fault; it&#8217;s the person misusing it.</p>
<p><span style="font-weight: bold;">Computer Science&#8217;s Vietnam</span><br />In 2004, Ted Neward famously called ORM <a href="http://blogs.tedneward.com/2006/06/26/The+Vietnam+Of+Computer+Science.aspx">Computer Science&#8217;s Vietnam</a>.  Encouraged by early successes, we got sucked into the quagmire.  There are plenty of reasons to be frustrated with ORM, but I&#8217;m not sure I agree with Ken&#8217;s.  I try to hit the 80/20 rule with ORM, and use it where it makes sense.  When I get into a convoluted transaction or need to do a large batch of operations, I&#8217;m not afraid to dive into SQL and do the work in a stored procedure.  I think it&#8217;s a good mix.  How about you?</p>
<p><span style="font-style: italic;">Photo Credit: </span><a style="font-style: italic;" href="http://www.flickr.com/people/meesterdickey/">Ryan Dickey</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cereslogic.com/pages/2008/06/16/why-you-should-not-not-use-orm/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Use Hibernate Validators to find Nasty DataTruncation exceptions</title>
		<link>http://www.cereslogic.com/pages/2008/06/10/use-hibernate-validators-to-find-nasty/</link>
		<comments>http://www.cereslogic.com/pages/2008/06/10/use-hibernate-validators-to-find-nasty/#comments</comments>
		<pubDate>Wed, 11 Jun 2008 00:14:00 +0000</pubDate>
		<dc:creator>mdesjardins</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jpa]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/2008/06/use-hibernate-validators-to-find-nasty-datatruncation-exceptions/</guid>
		<description><![CDATA[If you develop Hibernate applications against either Sybase or MS SQL Server databases, you may have had the pleasure of seeing this little gem: 09:13:22,155 WARN [] org.hibernate.util.JDBCExceptionReporter &#8211; SQL Error: 0, SQLState: 2200109:13:22,155 ERROR [] org.hibernate.util.JDBCExceptionReporter &#8211; Data truncation09:13:22,155 WARN [] org.hibernate.util.JDBCExceptionReporter &#8211; SQL Error: 8152, SQLState: 2200109:13:22,155 ERROR [] org.hibernate.util.JDBCExceptionReporter &#8211; String or [...]]]></description>
			<content:encoded><![CDATA[<p>If you develop Hibernate applications against either Sybase or MS SQL Server databases, you may have had the pleasure of seeing this little gem:</p>
<p><span style="font-size:78%;"><span style="font-family:courier new;">09:13:22,155  WARN [] org.hibernate.util.JDBCExceptionReporter &#8211; SQL Error: 0, SQLState: 22001</span><br /><span style="font-family:courier new;">09:13:22,155 ERROR [] org.hibernate.util.JDBCExceptionReporter &#8211; Data truncation</span><br /><span style="font-family:courier new;">09:13:22,155  WARN [] org.hibernate.util.JDBCExceptionReporter &#8211; SQL Error: 8152, SQLState: 22001</span><br /><span style="font-family:courier new;">09:13:22,155 ERROR [] org.hibernate.util.JDBCExceptionReporter &#8211; String or binary data would be truncated.</span><br /><span style="font-family:courier new;">09:13:22,159 ERROR [] org.hibernate.event.def.AbstractFlushingEventListener &#8211; Could not synchronize database state with session</span><br /><span style="font-family:courier new;"></span><span style="font-family:courier new;">.</span><br /><span style="font-family:courier new;">.</span><br /><span style="font-family:courier new;">.</span><br /><span style="font-family:courier new;">Caused by: java.sql.DataTruncation: Data truncation</span></span></p>
<p>The most maddening thing about these errors is that the database won&#8217;t tell you <span style="font-style: italic;">which</span> column is being truncated.  A likely scenario is that you&#8217;ve developed a Web or Swing UI that permits the user to enter a value for a String field which is ultimately persisted to a database column, and the UI is not restricting the maximum length of the user&#8217;s input to the size of that the column supports.  The question is, which field is the offender?</p>
<p><span style="font-weight: bold;">Hibernate Validators to the Rescue!</span><br />Situations like this are why it&#8217;s a pretty good idea to validate your data at the domain layer of your project, and not rely on your database and presentation layer to do all of the validation. Fortunately, Hibernate makes this pretty painless with validator annotations.  Just import the org.hibernate.validator.Length annotation, and add the @Length annotation in your entity class, e.g.:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;description&quot;</span>,length<span style="color: #339933;">=</span><span style="color: #cc66cc;">20</span><span style="color: #009900;">&#41;</span>
@Length<span style="color: #009900;">&#40;</span>max<span style="color: #339933;">=</span><span style="color: #cc66cc;">20</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> description<span style="color: #339933;">;</span></pre></div></div>

<p>Note that putting the length attribute in the @Column annotation <span style="font-style: italic;">is not enough</span>.  That attribute is used for generating DDL, but will not cause any validation to take place.</p>
<p>Now that our new Annotation is in place, we get the <span style="font-style: italic;">slightly</span> more useful stack-trace below:</p>
<p><span style="font-size:78%;"><span style="font-family:courier new;">org.hibernate.validator.InvalidStateException: validation failed for: us.mikedesjardins.data.persist.MyClass</span><br /><span style="font-family:courier new;">        at org.hibernate.validator.event.ValidateEventListener.validate(ValidateEventListener.java:148)</span><br /><span style="font-family:courier new;">        at org.hibernate.validator.event.ValidateEventListener.onPreInsert(ValidateEventListener.java:172)</span><br /><span style="font-family:courier new;">        at org.hibernate.action.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:119)</span><br /><span style="font-family:courier new;">.</span><br /><span style="font-family:courier new;">.</span><br /><span style="font-family:courier new;">.</span><br /><span style="font-family:courier new;"></span></span><br />Of course, you should catch these exceptions and do something less hostile with them.  For now, we&#8217;ll just log the details and re-throw so you can get the general gist of what you can do.  Here&#8217;s a generic insert method in a DAO base class:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> insert<span style="color: #009900;">&#40;</span>T valueObject, <span style="color: #000000; font-weight: bold;">Class</span>... <span style="color: #006633;">clazz</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
   Session s <span style="color: #339933;">=</span> getSession<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   s.<span style="color: #006633;">save</span><span style="color: #009900;">&#40;</span>valueObject<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   s.<span style="color: #006633;">flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   s.<span style="color: #006633;">refresh</span><span style="color: #009900;">&#40;</span>valueObject<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span>InvalidStateException v<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   setToRollback<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   log.<span style="color: #006633;">error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;insert(), failed validation &quot;</span> <span style="color: #339933;">+</span> valueObject.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, v<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #003399;">InvalidValue</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> invalid <span style="color: #339933;">=</span> v.<span style="color: #006633;">getInvalidValues</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i<span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>invalid.<span style="color: #006633;">length</span><span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
     <span style="color: #003399;">InvalidValue</span> bad <span style="color: #339933;">=</span> invalid<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
     log.<span style="color: #006633;">error</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;insert(), &quot;</span> <span style="color: #339933;">+</span> bad.<span style="color: #006633;">getPropertyPath</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
     <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;:&quot;</span> <span style="color: #339933;">+</span> bad.<span style="color: #006633;">getPropertyName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
     <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;:&quot;</span> <span style="color: #339933;">+</span> bad.<span style="color: #006633;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
   <span style="color: #000000; font-weight: bold;">throw</span> v<span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><span style="font-size:100%;">As you can see, the InvalidStateException contains an array of InvalidValue objects which describe the nature of the validation error.  You can either log this information, or even present it to the user.</p>
<p>Hope that helps!  Do you use Hibernate&#8217;s validator annotations for something nifty?  Let us know in the comments!<br /></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cereslogic.com/pages/2008/06/10/use-hibernate-validators-to-find-nasty/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Hibernate Song</title>
		<link>http://www.cereslogic.com/pages/2008/06/06/the-hibernate-song/</link>
		<comments>http://www.cereslogic.com/pages/2008/06/06/the-hibernate-song/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 14:32:00 +0000</pubDate>
		<dc:creator>mdesjardins</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/2008/06/the-hibernate-song/</guid>
		<description><![CDATA[(to the tune of The Spiderman Theme Song from the original cartoon series) Hibernate, HibernateO/R Mapping sure is greatGavin King, and H-Q-LMake my life a living hellLook out! Here comes Hibernate! Mapping Files in HibernateWish my team would annotateAre its queries optimized?Who knows &#8211; it&#8217;s always a surpriseHey there, there goes Hibernate! Don&#8217;t fetch data [...]]]></description>
			<content:encoded><![CDATA[<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mikedesjardins.us/blog/uploaded_images/spiderman-704658.png"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://mikedesjardins.us/blog/uploaded_images/spiderman-704633.png" alt="" border="0" /></a>(to the tune of <span style="font-style: italic;">The Spiderman Theme Song</span> from the original cartoon series)</p>
<p>Hibernate, Hibernate<br />O/R Mapping sure is great<br />Gavin King, and H-Q-L<br />Make my life a living hell<br />Look out!  Here comes Hibernate!</p>
<p>Mapping Files in Hibernate<br />Wish my team would annotate<br />Are its queries optimized?<br />Who knows &#8211; it&#8217;s always a surprise<br />Hey there, there goes Hibernate!</p>
<p>Don&#8217;t fetch data now<br />Lazy load, &#8216;cuz you might guess<br />I don&#8217;t need it now<br />Hibernate, you do know best!</p>
<p>Hibernate, Hibernate<br />Friendly neighborhood Hibernate<br />Grab the jars, and climb aboard<br />OO models are your reward<br />To it&#8230;<br />Relational DBs are old-school<br />When you need a complex tool<br />You need the Hibernate!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cereslogic.com/pages/2008/06/06/the-hibernate-song/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Who is running that horrible Hibernate query?  Find out with comments</title>
		<link>http://www.cereslogic.com/pages/2008/06/01/who-is-running-that-horrible-hibernate/</link>
		<comments>http://www.cereslogic.com/pages/2008/06/01/who-is-running-that-horrible-hibernate/#comments</comments>
		<pubDate>Sun, 01 Jun 2008 10:32:00 +0000</pubDate>
		<dc:creator>mdesjardins</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[jpa]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/?p=30</guid>
		<description><![CDATA[The Dreaded Search Function I&#8217;ve worked at several jobs where the users have asked for a general-purpose search function in their application. It&#8217;s the sort of thing where people want the ability to search on, e.g., all customers with a last name that starts with SM, or all of the customers with a balance greater [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-weight: bold;">The Dreaded Search Function</span><br />
I&#8217;ve worked at several jobs where the users have asked for a general-purpose search function in their application.  It&#8217;s the sort of thing where people want the ability to search on, e.g., all customers with a last name that starts with SM, or all of the customers with a balance greater than 1000.00, etc.</p>
<p>If you can resist the request to build such a thing, <span style="font-style: italic;">then by all means, <span style="font-weight: bold;">don&#8217;t implement it</span></span>.  End-users have a knack for creating queries which will bring your database to its knees, no matter how clever you think you are with indexing or UI design.</p>
<p>If you must do it, you&#8217;ll want to keep a close eye on how its used from the outset for when the inevitable nightmare query is run.  One way to do this is by using Hibernate&#8217;s comments feature.</p>
<p><span style="font-weight: bold;">Use Comments to Hunt them Down</span><br />
My colleague <a href="http://mattbrock.net/">Matt Brock</a> implemented something like this where we work. Suppose you have a general method for creating an HQL query in a DAO class, the method could look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">protected</span> Query createQuery<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> hql<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">return</span> getSession<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">createQuery</span><span style="color: #009900;">&#40;</span>hql<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setComment</span><span style="color: #009900;">&#40;</span>getUsername<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Next, make sure Hibernate&#8217;s SQL logging and comment logging is enabled in your hibernate.hbm.xml (warning &#8211; this log can get pretty huge):</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;">&nbsp;
true
true
.
.
.</pre></div></div>

<p>Your log will now contain the users who are executing each query, like this:</p>
<p><span style="font-size:78%;"><span style="font-family:courier new;">Hibernate: /* johndoe */ select customer0_.customer_id as col_0_0_, customer0_.cust_company_name from CUSTOMER customer0_ where (customer0_.customer_id=12136 or customer0_.customer_id=16884 or customer0_.customer_id=11150 or customer0_.customer_id=155 or customer0_.customer_id</span><br />
<span style="font-family:courier new;">=27265 or customer0_.customer_id=697 or customer0_.customer_id=4133 or customer0_.customer_id=248 or customer0_.customer_id=2550 or customer0_.customer_id=8449)</span><br />
</span></p>
<p>One caveat: this may not work with stored procedures &#8211; SQL Server, in particular, will get nasty if you try to execute a stored procedure with Hibernate comments attached to it.</p>
<p>Happy Hibernating!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cereslogic.com/pages/2008/06/01/who-is-running-that-horrible-hibernate/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Pizza Shop III : JPA Event Listeners</title>
		<link>http://www.cereslogic.com/pages/2008/03/31/pizza-shop-iii-jpa-event-listeners/</link>
		<comments>http://www.cereslogic.com/pages/2008/03/31/pizza-shop-iii-jpa-event-listeners/#comments</comments>
		<pubDate>Mon, 31 Mar 2008 16:44:00 +0000</pubDate>
		<dc:creator>mdesjardins</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[pizzashop]]></category>

		<guid isPermaLink="false">http://mikedesjardins.us/wordpress/2008/03/pizza-shop-iii-jpa-event-listeners/</guid>
		<description><![CDATA[This comment was recently posted to one of my blog entries a while back: Let us consider I am adding &#8216;CreatedBy&#8217; and &#8216;ModifiedBy&#8217; columns in all the tables to be used for audit purposes. Ideally these columns would be populated by the user id who has logged into the application. &#8211; @Madhan So, let&#8217;s say [...]]]></description>
			<content:encoded><![CDATA[<p>This comment was recently posted to one of my blog entries a while back:</p>
<blockquote><p><span class="PostFooter">Let us consider I am adding  &#8216;CreatedBy&#8217;  and &#8216;ModifiedBy&#8217; columns in all the tables to be used for audit purposes. Ideally these columns would be populated by the user id who has logged into the application.   &#8211; @Madhan</span></p>
</blockquote>
<p>So, let&#8217;s say your data model has some tables with a columns that indicate <a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mikedesjardins.us/blog/uploaded_images/1764153258_11bbbcb337-715981.jpg"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 234px; height: 175px;" src="http://mikedesjardins.us/blog/uploaded_images/1764153258_11bbbcb337-715955.jpg" alt="" border="0" /></a>the last person who touched a record, like Madhan&#8217;s example above.  In most applications, the end-users of the database client share a common login to the database, and have individual logins which are specific to the application&#8217;s domain (i.e., you don&#8217;t have a database login mapped to each end user; maintaining this scheme would be a nightmare).  For that reason, triggers can&#8217;t be used as a solution, because database triggers don&#8217;t know anything about which application end-user is responsible for making a data change.</p>
<p>The last thing you want to do is litter your codebase with snippets of code that set the username on your persisted objects manually; not only is it unnecessary duplication, but you&#8217;ll probably also end up missing cases where you should be setting the username.</p>
<p><span style="font-weight: bold;">EventListeners to the Rescue</span><br />Fortunately, JPA supports the notion of &#8220;EventListeners.&#8221;  An event listener intercepts many of the API calls that modify a persisted object&#8217;s lifecycle, and thus may be used to inject business logic that needs to be duplicated over many different objects.  AOP aficionados might refer to this as a cross-cutting &#8220;aspect&#8221; of the domain layer.</p>
<p><span style="font-weight: bold;">Return to the Pizza Shop</span><br />Readers of my blog (all three of them, including me) might recall my venerable Pizza Shop example.  Here are the earlier Pizza Shop posts if you&#8217;d like to catch up:  <a href="http://mikedesjardins.us/blog/2008/01/new-jpa-tutorial-pizza-shop.html">Part 1</a> and <a href="http://mikedesjardins.us/blog/2008/03/pizza-shop-2-totaling-jpa-order-use.html">Part 2</a>. I&#8217;m going to drag the Pizza Shop out again to demonstrate how to create an &#8220;audited&#8221; table, which shows the last user who modified a record. As always, the source is available <a href="http://mikedesjardins.us/pizzashop-3.1.tar.gz">here</a>, and it&#8217;s been tested against MySQL, Postgres, and MS SQL Server, with Hibernate, OpenJPA, and TopLink.</p>
<p>This takes just five easy steps&#8230; four, really, &#8216;cuz the fourth step creates a mock object for testing, so it doesn&#8217;t really count!</p>
<p><span style="font-weight: bold;">Step One &#8211; New schema</span><br />Add a nullable column named username to the Order table&#8230; something like this should work if you have existing pizzashop schema for some reason:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">ADD</span> username <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p><span style="font-weight: bold;">Step Two &#8211; Create an Interface and Implement It</span><br />This step isn&#8217;t strictly necessary, but it&#8217;s probably safe to assume that we&#8217;ll want to add this functionality to other tables someday.  The interface just adds accessor methods for the username:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> AuditedObject <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getUsername<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setUsername<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> username<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Then, make the Order table implement AuditedObject.  Add a member variable with a mapping to the username column to the Order table, and corresponding accessor methods:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Order <span style="color: #000000; font-weight: bold;">implements</span> IdObject, AuditedObject <span style="color: #009900;">&#123;</span>
.
.
  @Basic @Column<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;username&quot;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> username<span style="color: #339933;">;</span>
.
.
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getUsername<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">return</span> username<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setUsername<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> username<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">username</span> <span style="color: #339933;">=</span> username<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
.
.
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><span style="font-weight: bold;">Step Three &#8211; Add an EntityListener Annotation</span><br />This is the secret sauce.  In the JPA Framework, EventListeners allow you to fire some trigger code when a lifecycle event occurs on a persisted object.  You do this by associating your persisted class with an EventListener class.  We&#8217;ll implement our EventListener class after we&#8217;ve added the following annotations:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@<span style="color: #003399;">Entity</span> @Table<span style="color: #009900;">&#40;</span>name<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;PIZZA_ORDER&quot;</span><span style="color: #009900;">&#41;</span>
@EntityListeners<span style="color: #009900;">&#40;</span>AuditedEntityListener.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Order <span style="color: #000000; font-weight: bold;">implements</span> IdObject, AuditedObject <span style="color: #009900;">&#123;</span>
.
.</pre></div></div>

<p><span style="font-weight: bold;">Step Four &#8211; Write a Mock Object for the Username for Testing</span><br />In the real world, you&#8217;d probably stuff the username into the servlet context object.  For our simple tests, we&#8217;ll need to mock up an object to maintain a username for the duration of our tests.  It can be something stupidly simple, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MockContext <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">String</span> username<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">String</span> getUsername<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">return</span> username<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> setUsername<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> username<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      MockContext.<span style="color: #006633;">username</span> <span style="color: #339933;">=</span> username<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>We&#8217;ll set the username at the start of our tests, and read the username from our MockContext from the EventListener.</p>
<p><span style="font-weight: bold;">Step Five &#8211; Write the EntityListener class</span><br />JPA allows you to inercept method calls using seven annotations:
<ul>
<li>@PrePersist and @PostPersist are called before and after an object is persisted.  </li>
<li>@PreUpdate and @PostUpdate are called before and after synchronization with the database.  @PreRemove and @PostRemove are called before and after an object is removed from the persistent state.</li>
<li>@PostLoad is invoked immediately after an object is loaded from the database.</li>
</ul>
<p>In our case, we&#8217;re going to populate the username instance variable when the object is persisted, so we will want to create an EntityListener class with the @PrePersist annotation.  The method&#8217;s signature takes an Object parameter which is the object getting updated, and returns void.  The class will look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> AuditedEntityListener <span style="color: #009900;">&#123;</span>
  @PrePersist
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> updateUser<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> o<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>o <span style="color: #000000; font-weight: bold;">instanceof</span> AuditedObject<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">String</span> username <span style="color: #339933;">=</span> MockContext.<span style="color: #006633;">getUsername</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>AuditedObject<span style="color: #009900;">&#41;</span>o<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setUsername</span><span style="color: #009900;">&#40;</span>username<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><span style="font-style: italic;">Voila</span>!  When you run the tests, the username fields are populated and persisted!</p>
<p>Audit M&amp;M&#8217;s Photo Courtesy <a href="http://josephhall.org">Joe Hall</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cereslogic.com/pages/2008/03/31/pizza-shop-iii-jpa-event-listeners/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

