<?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>Pramatr Blog &#187; Spring</title>
	<atom:link href="http://www.pramatr.com/blog/category/spring/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pramatr.com/blog</link>
	<description>A collection of articles from pramatr.com on technology, security, software and anything we find interesting</description>
	<lastBuildDate>Mon, 29 Mar 2010 19:48:11 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Spring Recipes: A Problem-Solution Approach</title>
		<link>http://www.pramatr.com/blog/2009/02/17/spring-recipes-a-problem-solution-approach/</link>
		<comments>http://www.pramatr.com/blog/2009/02/17/spring-recipes-a-problem-solution-approach/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 14:04:13 +0000</pubDate>
		<dc:creator>pramatr</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Examples]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Opinion]]></category>
		<category><![CDATA[Resources]]></category>

		<guid isPermaLink="false">http://pramatr.com/?p=421</guid>
		<description><![CDATA[I recently had the pleasure of reading Spring Recipes: A Problem-Solution Approach. I first began reading the sample chapters released on the authors website, so when the book was finally finished I was really looking forward to getting hold of a copy. When it arrived I was amazed to see that it weighed in at [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.apress.com/book/view/1590599799"><img class="alignleft size-medium wp-image-535" title="springrecipes" src="http://pramatr.files.wordpress.com/2009/02/springrecipes.jpg?w=228" alt="springrecipes" width="228" height="300" /></a>I recently had the pleasure of reading <a href="http://apress.com/book/view/1590599799">Spring Recipes: A Problem-Solution Approach</a>. I first began reading the sample chapters released on the authors website, so when the book was finally finished I was really looking forward to getting hold of a copy. When it arrived I was amazed to see that it weighed in at a hefty 752 pages, but that really shouldn&#8217;t put you off.</p>
<p>Spring Recipes covers Spring 2.5 (and earlier versions) taking it from the simplest concepts right through to the most advanced level. The book is divided into nineteen chapters organised into three parts; Core, Fundamentals and Advanced. Each part builds on the previous ones to grow your understanding of all aspects of the Spring framework, for this reason the book is best read cover to cover.</p>
<p>This book is in no way filler and is packed full of content covering not only the <a href="http://www.springsource.org/about">Spring framework</a> and but also several common Spring <a href="http://www.springsource.org/projects">projects</a> including; <a href="http://static.springframework.org/spring-security/site/index.html">Spring Security</a>, <a href="http://www.springsource.org/webflow">Spring Web Flow</a> and <a href="http://static.springframework.org/spring-ws/sites/1.5/">Spring Web Services</a>. For anyone that knows Spring (and it&#8217;s associated projects), this is a huge amount of information to cover in just one book, but this book really does deliver!</p>
<p>As the author puts it; <em>“Reading Spring Recipes will help you master the most important 80 percent of Spring&#8217;s features with just 20 percent of the effort you would need to learn them all.”</em> If you are already using Spring, this book will serve as an invaluable reference and companion guide for future development. If you are a newcomer to Spring, this book will serve as an excellent launch pad to get you up, running and productive with Spring very quickly.</p>
<h2><strong>Structure</strong></h2>
<p>Each of the recipes covered in the book follows; a problem, solution and then how it works approach. This approach lays out many of the common FAQ style questions that come up on <a href="http://forum.springframework.org/">Spring Forum</a> in an accessible way; clearly outlining the problem and mapping the path to the solution. This book also acts an excellent companion to the <a href="http://static.springframework.org/spring/docs/2.5.x/reference/">Spring Reference manual</a>, which is sometimes difficult to read in places and lacks the array of examples this book provides.</p>
<h2><strong>Audience</strong></h2>
<p>The intended audience for Spring Recipes, is any Java programmer hoping to learn more about Spring. No prior knowledge of Spring is required as this book covers it all right from core concepts such as inversion of control (or Ioc). This book is accessible to anyone who has heard the hype about Spring and simply wants to learn more about it and how they can leverage it&#8217;s power. This book gives Java developers hands-on experience using the Spring framework with real-world examples, this experience can be transferred straight into your Spring project.</p>
<h2><strong>Chapters</strong></h2>
<h3><strong>Part 1: Core</strong></h3>
<p>This part focuses on the core concepts and mechanisms of the Spring framework. The chapters in this part aim to familiarize you with Spring&#8217;s core. As a newcomer to Spring <strong>Chapter 1</strong> introduces the concept of inversion of control the core foundation of Spring. It explains how and IoC container works, but also why it is useful and beneficial to use one. This chapter serves as an excellent introduction to IoC and is invaluable to anyone who isn&#8217;t quite sure why they should use a container based approach. This chapter is a <strong>must</strong> for anyone new to Spring or anyone trying to deliver it to a new audience.</p>
<p><strong>Chapters 2-4</strong> build on the IoC introduction, explaining how to setup and configure a new Spring project and apply the basics of Spring configuration. These first four chapters are the foundation for the rest of the book and are a must read for anyone who has never used Spring before and even advanced users may find useful hints and tips within. <strong>Chapters 5-6</strong> cover the extremely powerful approach of <a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming">AOP</a>, introducing <a href="http://en.wikipedia.org/wiki/Cross-cutting_concern">crosscutting concerns</a> and how these can be configured with Spring. This technique can be extremely useful to provide trace logging, caching and other crosscutting concerns such as security. This is a <strong>must</strong> read for anyone using Spring, even if you are not directly leveraging <a href="http://static.springframework.org/spring/docs/2.5.x/reference/aop.html">Spring AOP</a> or <a href="http://www.eclipse.org/aspectj/">AspectJ</a>. Spring AOP lays the foundation for introducing how Spring provides features such as transparent transaction support and method level authorization checking.</p>
<h3><strong>Part 2 : Fundamentals</strong></h3>
<p>This part has a split focus, it introduces Spring&#8217;s Data Access support, Web integration and also Testing support. <strong>Chapter 7</strong> introduces one of the most important aspects of Spring&#8217;s <a href="http://static.springframework.org/spring/docs/2.5.x/reference/spring-middle-tier.html">data access support</a> in the form of <a href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/jdbc/core/JdbcTemplate.html">JdbcTemplate</a>. This shows the reader how they can use JdbcTemplate to prevent the use of direct JDBC and instead let Spring handle all of the boiler plate code. As JdbcTemplate removes the need for the common try/catch/finally/try/catch code seen with JDBC, the code is much cleaner and much more readable. Along with this support, the Spring <a href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/dao/DataAccessException.html">DataAccessException</a> hierarchy is introduced which provides a rich set of common exceptions to provide a more granular handling approach.</p>
<p><strong>Chapter 8</strong> introduces Spring&#8217;s excellent <a href="http://static.springframework.org/spring/docs/2.5.x/reference/transaction.html">transaction management</a> support and explains in great detail all of the <a href="http://static.springframework.org/spring/docs/2.5.x/reference/transaction.html#transaction-declarative-txadvice-settings">various</a> propagation behaviours and isolation levels. This chapter is one of my favourites as it not only introduces the concept of Spring transaction support but transactions in general. It&#8217;s accessible to everyone and extremely useful when mentoring new developers.</p>
<p><strong>Chapter 9</strong> discusses how to integrate Spring with existing ORM frameworks, making their usage within the application seamless. This provides multiple approaches to integration allowing you to build on existing Spring classes, or completely decouple your classes from Spring removing the need for any Spring imports within your code. <strong>Chapters 10-11</strong> discuss Spring&#8217;s popular MVC framework and also discuss how many other leading web frameworks can be integrated with a Spring application. As many of the projects I have worked on in the past have used <a href="http://struts.apache.org/">Struts</a>, Chapter 11 was particularly useful to outline all of the options available to use Spring and Struts together.</p>
<p>This part finishes with the introduction of <a href="http://static.springframework.org/spring/docs/2.5.x/reference/testing.html">Spring Testing Support</a>, teaching you not only what features Spring has to offer but also how it integrates with popular testing frameworks such as <a href="http://www.junit.org/">JUnit</a> and <a href="http://testng.org">TestNG</a>. As the Spring Testing support has been overhauled, it was great that this book covered the <a href="http://static.springframework.org/spring/docs/2.5.x/reference/testing.html#testcontext-framework">TestContext</a>framework, but also legacy test classes to cover older versions of JUnit and TestNG. This chapter helps you leverage not only IoC for your tests but also transaction support, mock testing and also MVC integration testing. This approach enables you to easily decouple your code from your tests, providing first class support for all your testing needs.</p>
<h3><strong>Part 3 : Advanced</strong></h3>
<p>For anyone that has mastered the first twelve chapters, <strong>Chapter 13</strong> is where things start to get really interesting. This chapter is dedicated to one of the most scary Spring projects, namely <a href="http://static.springsource.org/spring-security/site/index.html">Spring Security</a> (formerly known as Acegi). Spring Security provides a full range of authentication, authorization and access control options which allow it to secure a standalone Java application or a web-based application. This book focuses on version 2.x onwards which <a href="http://blog.springsource.com/2008/04/17/spring-security-20-final-release-no-more-dead-fairies/">dramatically</a> reduced the size of the required configuration and also its complexity. Spring Security can be a difficult subject to tackle as it&#8217;s often hard for developers to understand it&#8217;s concepts, but this chapter builds security into the example application in piecemeal steps. This demystifies many of the problematic areas of Spring Security whilst addressing the common problems a new developer might face.</p>
<p><strong>Chapter 14</strong> covers the portlet application development using the Spring Portlet MVC framework, highlighting the portlet-specific features which differ from the standard Spring MVC framework. If you don&#8217;t require the portlet features currently within your application, this chapter can safely be skipped as the next one is another gem. <strong>Chapter 15</strong> covers the <a href="http://www.springsource.org/webflow">Spring Web Flow</a> framework which addresses the three major pain–points facing web application developers: user interface navigation control, state management, and modularity. Spring Web Flow offers a <a href="http://static.springframework.org/spring-webflow/docs/2.0.x/reference/htmlsingle/spring-webflow-reference.html#flow-overview">flow</a> definition language which encapsulates a reusable sequence of steps that can execute in different contexts. This framework is extremely flexible and powerful, but this chapter provides a great introduction into what is a very large subject.</p>
<p><strong>Chapter 16</strong> introduces the remoting integration that Spring provides for various technologies such as RMI, Hessian, Burlap, HTTP Invoker, and Web Services. Having already been familiar with many of these technologies, this chapter provides an excellent insight into how these can be integrated with Spring and how quickly this can be achieved. This chapter concludes with a look at Spring Web Services including how to develop contract-first web services. <strong>Chapter 17</strong> discusses how to develop EJB 2.x and 3.0 components with Spring&#8217;s EJB support, and how to use Spring&#8217;s JMS support to simplify sending, receiving, and listening to JMS messages. This introduces a powerful concept of <a href="http://blog.springsource.com/2006/08/11/message-driven-pojos/">message-driven POJOs</a>for those who like the concept of message-driven beans (MDBs) but don&#8217;t want the restrictions of an EJB container.</p>
<p><strong>Chapter 18</strong> demonstrates how easily Spring beans can be exported as JMX MBeans with relative ease in comparison to the typical approach. It continues to extend this by providing remote access, auto-detection and notification. This chapter continues by introducing Spring&#8217;s email support which removes the reliance on <a href="http://java.sun.com/products/javamail/">JavaMail</a> specific mail sessions and exceptions. This provides an abstraction which is independent making it easy to switch to another e-mail API. This chapter finishes with a look at the options available for scheduling tasks within the Spring framework, this integrates with the JDK Timer and also <a href="http://www.opensymphony.com/quartz/">Quartz</a> scheduler.</p>
<p><strong>Chapter 19</strong>, this part and the book concludes with a look at the various scripting languages that can used with Spring applications including; JRuby, Groovy and BeanShell. One of the most powerful features of using scripts is that any changes made to these can be detected by Spring and thus the beans can be <a href="http://static.springframework.org/spring/docs/2.5.x/reference/dynamic-language.html#dynamic-language-refreshable-beans">refreshed</a> automatically. This is of great benefit when you wish to avoid the long compile, deploy and test cycles or the application cannot be taken down regularly for maintenance. This chapter demonstrates how scripted beans can be added to your application quickly and simply using Spring.</p>
<h2><strong>Summary</strong></h2>
<p>This book has undertaken a mammoth task, trying to squeeze Spring and associated projects all into one book. This book is very clearly written, with well-structured, concise examples that get to the heart of the problem without complicating it with unnecessary detail. The examples provide solutions to real world problems instead of taking the form of the simplistic examples found in many other technology books. My only real minor criticism of this book is it&#8217;s scope and size. Given the huge undertaking, there are obviously going to be some areas which only provide a minimal amount of information. This should be expected given the vast array of information covered, but there are a range of <a href="http://www.apress.com">Apress</a> <a href="http://www.apress.com/book/view/1430216247">books</a> which can build on this foundation. I would still give this book five out of five and rate it as one of the best framework specific books I&#8217;ve read.</p>
<p>This book should accompany anyone starting their journey with the Spring framework and even seasoned developers. It can take you from knowing nothing about the Spring framework to knowing pretty much everything you need to create a fully functional web application with all the bells and whistles you&#8217;d expect. It provides information and examples on numerous integration points with other popular open source frameworks and languages allowing you to truly become a Spring expert. Read it, read it again and keep it on your bookshelf as a solid reference for the Spring framework.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pramatr.com/blog/2009/02/17/spring-recipes-a-problem-solution-approach/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>SQL n + 1 Selects Explained</title>
		<link>http://www.pramatr.com/blog/2009/02/05/sql-n-1-selects-explained/</link>
		<comments>http://www.pramatr.com/blog/2009/02/05/sql-n-1-selects-explained/#comments</comments>
		<pubDate>Thu, 05 Feb 2009 06:00:47 +0000</pubDate>
		<dc:creator>pramatr</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Refactoring]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[Code Review]]></category>
		<category><![CDATA[Examples]]></category>
		<category><![CDATA[Improvement]]></category>
		<category><![CDATA[Jdbc]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Smells]]></category>

		<guid isPermaLink="false">http://pramatr.com/?p=426</guid>
		<description><![CDATA[The SQL n + 1 selects problem is extremely common but I have often found that many people have either never heard of it or simply don&#8217;t understand it. It is actually very easy to introduce a problem like this into your code, but it&#8217;s also very easy to resolve as well. Problems like this [...]]]></description>
			<content:encoded><![CDATA[<p>The SQL n + 1 selects problem is extremely common but I have often found that many people have either never heard of it or simply don&#8217;t understand it. It is actually very easy to introduce a problem like this into your code, but it&#8217;s also very easy to resolve as well. Problems like this are best explained with an example; so imagine we have a table called users and another called user_roles. These tables are setup with a one-to-many relationship, meaning that one user (e.g. jsmith) can have many roles (e.g. Administrator, Auditor, Developer). Many people might implement something like this;</p>
<blockquote>
<pre><span style="font-size:small;"><strong>public</strong> <span style="color:#2040a0;">Iterable</span><span style="color:#4444ff;">&lt;</span><span style="color:#2040a0;">User</span><span style="color:#4444ff;">&gt;</span> <span style="color:#2040a0;">allUsers</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
    <strong>final</strong> <span style="color:#2040a0;">String</span> <span style="color:#2040a0;">selectUsers</span> <span style="color:#4444ff;">=</span> <span style="color:#008000;">"select users.username, users.email, " +</span>
        <span style="color:#008000;">"users.last_password_change from users"</span><span style="color:#4444ff;">;</span>
    <strong>return</strong> <span style="color:#2040a0;">getJdbcTemplate</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span>.<span style="color:#2040a0;">query</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">selectUsers</span>, <strong>new</strong> <span style="color:#2040a0;">Object</span><span style="color:#4444ff;"><strong>[</strong></span><span style="color:#4444ff;"><strong>]</strong></span> <span style="color:#4444ff;"><strong>{</strong></span><span style="color:#4444ff;"><strong>}</strong></span>,
                <strong>new</strong> <span style="color:#2040a0;">ParameterizedRowMapper</span><span style="color:#4444ff;">&lt;</span><span style="color:#2040a0;">User</span><span style="color:#4444ff;">&gt;</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
        <strong>public</strong> <span style="color:#2040a0;">User</span> <span style="color:#2040a0;">mapRow</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">ResultSet</span> <span style="color:#2040a0;">resultSet</span>, <strong>int</strong> <span style="color:#2040a0;">rowNumber</span><span style="color:#4444ff;"><strong>)</strong></span> <strong>throws</strong> <span style="color:#2040a0;">SQLException</span> <span style="color:#4444ff;"><strong>{</strong></span>
            <span style="color:#2040a0;">String</span> <span style="color:#2040a0;">username</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">resultSet</span>.<span style="color:#2040a0;">getString</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"username"</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
            <span style="color:#2040a0;">String</span> <span style="color:#2040a0;">email</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">resultSet</span>.<span style="color:#2040a0;">getString</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"email"</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
            <span style="color:#2040a0;">Date</span> <span style="color:#2040a0;">lastPasswordChange</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">resultSet</span>.<span style="color:#2040a0;">getDate</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"last_password_change"</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
            <span style="color:#2040a0;">User</span> <span style="color:#2040a0;">user</span> <span style="color:#4444ff;">=</span> <strong>new</strong> <span style="color:#2040a0;">DefaultUser</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">username</span>, <span style="color:#2040a0;">email</span>, <span style="color:#2040a0;">lastPasswordChange</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
            <span style="color:#2040a0;">addRolesToUser</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">user</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
            <strong>return</strong> <span style="color:#2040a0;">user</span><span style="color:#4444ff;">;</span>
        <span style="color:#4444ff;"><strong>}</strong></span>
    <span style="color:#4444ff;"><strong>}</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
<span style="color:#4444ff;"><strong>}</strong></span>

<strong>private</strong> <strong>void</strong> <span style="color:#2040a0;">addRolesToUser</span><span style="color:#4444ff;"><strong>(</strong></span><strong>final</strong> <span style="color:#2040a0;">User</span> <span style="color:#2040a0;">user</span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
    <strong>final</strong> <span style="color:#2040a0;">String</span> <span style="color:#2040a0;">selectUserRoles</span> <span style="color:#4444ff;">=</span> <span style="color:#008000;">"select role_name from user_roles where username = ?"</span><span style="color:#4444ff;">;</span>
    <span style="color:#2040a0;">getJdbcTemplate</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span>.<span style="color:#2040a0;">query</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">selectUserRoles</span>, <strong>new</strong> <span style="color:#2040a0;">Object</span><span style="color:#4444ff;"><strong>[</strong></span><span style="color:#4444ff;"><strong>]</strong></span> <span style="color:#4444ff;"><strong>{</strong></span> <span style="color:#2040a0;">user</span>.<span style="color:#2040a0;">getPrincipalName</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>}</strong></span>,
                <strong>new</strong> <span style="color:#2040a0;">RowCallbackHandler</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
        <strong>public</strong> <strong>void</strong> <span style="color:#2040a0;">processRow</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">ResultSet</span> <span style="color:#2040a0;">resultSet</span><span style="color:#4444ff;"><strong>)</strong></span> <strong>throws</strong> <span style="color:#2040a0;">SQLException</span> <span style="color:#4444ff;"><strong>{</strong></span>
            <span style="color:#2040a0;">String</span> <span style="color:#2040a0;">rolename</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">resultSet</span>.<span style="color:#2040a0;">getString</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"role_name"</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
            <span style="color:#2040a0;">user</span>.<span style="color:#2040a0;">addRole</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">rolename</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
        <span style="color:#4444ff;"><strong>}</strong></span>
    <span style="color:#4444ff;"><strong>}</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
<span style="color:#4444ff;"><strong>}</strong></span></span></pre>
</blockquote>
<p>Reviewing the code we can see one query is executed to retrieve the users, the problem here is for each user another SQL statement needs to be executed to retrieve the roles. If the first query retrieved one user, this would require one additional query to retrieve the roles. If the first query retrieved a hundred users, this would require one hundred additional queries to retrieve the roles. The pattern will always be the same, one query for the users and n queries dependent on the number of users found, thus n + 1. Although this solution is functional, it does result in many unnecessary SQL statements being executed.</p>
<blockquote>
<pre><span style="font-size:small;"><strong>select</strong> users.username, users.email, users.last_password_change <strong>from</strong> users;
<strong>select</strong> role_name <strong>from</strong> user_roles <strong>where</strong> username = ?;
<strong>select</strong> role_name <strong>from</strong> user_roles <strong>where</strong> username = ?;
<strong>select</strong> role_name <strong>from</strong> user_roles <strong>where</strong> username = ?;
...</span></pre>
</blockquote>
<p>Shared resources are typically the bottleneck in most applications, so expensive or unnecessary SQL should be avoided if possible. As the application attempts to scale, this bottleneck can become extremely problematic and severely inhibit application performance. Fortunately this is a simple solutions to this problem; introducing a join into the query.</p>
<blockquote>
<pre><span style="font-size:small;"><strong>public</strong> <span style="color:#2040a0;">Iterable</span><span style="color:#4444ff;">&lt;</span><span style="color:#2040a0;">User</span><span style="color:#4444ff;">&gt;</span> <span style="color:#2040a0;">allUsers</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
    <strong>final</strong> <span style="color:#2040a0;">String</span> <span style="color:#2040a0;">selectUsers</span> <span style="color:#4444ff;">=</span>
        <span style="color:#008000;">"select users.username, users.email, users.last_password_change, user_roles.role_name "</span>
            <span style="color:#4444ff;">+</span> <span style="color:#008000;">"from users left join user_roles on (users.username = user_roles.username)"</span><span style="color:#4444ff;">;</span>
    <strong>final</strong> <span style="color:#2040a0;">Map</span><span style="color:#4444ff;">&lt;</span><span style="color:#2040a0;">String</span>, <span style="color:#2040a0;">User</span><span style="color:#4444ff;">&gt;</span> <span style="color:#2040a0;">users</span> <span style="color:#4444ff;">=</span> <strong>new</strong> <span style="color:#2040a0;">HashMap</span><span style="color:#4444ff;">&lt;</span><span style="color:#2040a0;">String</span>, <span style="color:#2040a0;">User</span><span style="color:#4444ff;">&gt;</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
    <span style="color:#2040a0;">getJdbcTemplate</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span>.<span style="color:#2040a0;">query</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">selectUsers</span>, <strong>new</strong> <span style="color:#2040a0;">Object</span><span style="color:#4444ff;"><strong>[</strong></span><span style="color:#4444ff;"><strong>]</strong></span> <span style="color:#4444ff;"><strong>{</strong></span><span style="color:#4444ff;"><strong>}</strong></span>, <strong>new</strong> <span style="color:#2040a0;">RowCallbackHandler</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
        <strong>public</strong> <strong>void</strong> <span style="color:#2040a0;">processRow</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">ResultSet</span> <span style="color:#2040a0;">resultSet</span><span style="color:#4444ff;"><strong>)</strong></span> <strong>throws</strong> <span style="color:#2040a0;">SQLException</span> <span style="color:#4444ff;"><strong>{</strong></span>
            <span style="color:#2040a0;">String</span> <span style="color:#2040a0;">username</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">resultSet</span>.<span style="color:#2040a0;">getString</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"username"</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
            <strong>if</strong> <span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;">!</span><span style="color:#2040a0;">users</span>.<span style="color:#2040a0;">containsKey</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">username</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
                <span style="color:#2040a0;">String</span> <span style="color:#2040a0;">email</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">resultSet</span>.<span style="color:#2040a0;">getString</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"email"</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
                <span style="color:#2040a0;">Date</span> <span style="color:#2040a0;">lastPasswordChange</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">resultSet</span>.<span style="color:#2040a0;">getDate</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"last_password_change"</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
                <span style="color:#2040a0;">User</span> <span style="color:#2040a0;">user</span> <span style="color:#4444ff;">=</span> <strong>new</strong> <span style="color:#2040a0;">DefaultUser</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">username</span>, <span style="color:#2040a0;">email</span>, <span style="color:#2040a0;">lastPasswordChange</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
                <span style="color:#2040a0;">users</span>.<span style="color:#2040a0;">put</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">username</span>, <span style="color:#2040a0;">user</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
            <span style="color:#4444ff;"><strong>}</strong></span>

            <span style="color:#2040a0;">String</span> <span style="color:#2040a0;">rolename</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">resultSet</span>.<span style="color:#2040a0;">getString</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"role_name"</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
            <strong>if</strong> <span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;">!</span><span style="color:#2040a0;">StringUtil</span>.<span style="color:#2040a0;">isNull</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">rolename</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
                <span style="color:#2040a0;">User</span> <span style="color:#2040a0;">user</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">users</span>.<span style="color:#2040a0;">get</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">username</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
                <span style="color:#2040a0;">user</span>.<span style="color:#2040a0;">addRole</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">rolename</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
            <span style="color:#4444ff;"><strong>}</strong></span>
        <span style="color:#4444ff;"><strong>}</strong></span>
    <span style="color:#4444ff;"><strong>}</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
    <strong>return</strong> <span style="color:#2040a0;">users</span>.<span style="color:#2040a0;">values</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
<span style="color:#4444ff;"><strong>}</strong></span></span></pre>
</blockquote>
<p>Although the code and SQL statement are slightly more complex that the original example, it results in much fewer SQL statements being executed. Instead of the n + 1 statements executed in the first example, one statement is executed that fetches all the required data. This typically results in much improved performance and as the numbers scale the improvement in performance can become much more apparent.</p>
<blockquote>
<pre><span style="font-size:small;"><strong>select</strong> users.username, users.email, users.last_password_change, user_roles.role_name
    <strong>from</strong> users left join user_roles <strong>on</strong> <strong>(</strong>users.username = user_roles.username);</span></pre>
</blockquote>
<p>As with all performance optimizations the most important thing is to measure the effect of the improvement. Performance optimizations aren&#8217;t always predictable so by taking measurements before and after the change, you can accurately know if you have actually improved the performance (or made it worse). A SQL join may be the most appropriate way of solving a problem such as this, but there are other alternatives such as <a href="http://ehcache.sourceforge.net/">caching</a> the data instead. Although the SQL n + 1 selects is an extremely common problem, is not always well understood and is often still found within code. It is very easy to introduce a problem like this into your code, but it&#8217;s also very easy to resolve as well. Next time you are viewing your debug output, see if you can spot SQL n + 1 selects.</p>
<p><strong>References</strong></p>
<p>Database access using <a href="http://pramatr.com/2008/08/19/spring-jdbctemplate-the-phantom-performance-problem/">Spring JdbcTemplate</a><br />
Preventing the n + 1 select problem when using <a href="http://www.hibernate.org/hib_docs/v3/reference/en-US/html/performance.html#performance-fetching-custom">Hibernate</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.pramatr.com/blog/2009/02/05/sql-n-1-selects-explained/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Are Conferences Really Worth The Money?</title>
		<link>http://www.pramatr.com/blog/2008/09/10/are-conferences-really-worth-the-money/</link>
		<comments>http://www.pramatr.com/blog/2008/09/10/are-conferences-really-worth-the-money/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 22:13:00 +0000</pubDate>
		<dc:creator>pramatr</dc:creator>
				<category><![CDATA[Opinion]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Conference]]></category>

		<guid isPermaLink="false">http://pramatr.com/2007/09/10/are-conferences-really-worth-the-money/</guid>
		<description><![CDATA[Nearly a year ago, I posted a question on Spring Forum entitled, &#8220;am I working for the wrong companies or is it just not that common to attend conferences?&#8221;. I&#8217;ve worked as a developer for over six years and as yet I&#8217;ve never had the opportunity to attend a single conference. I thought I might [...]]]></description>
			<content:encoded><![CDATA[<p>Nearly a year ago, I posted a question on <a href="http://forum.springframework.org/">Spring Forum</a> entitled, <em>&#8220;am I working for the wrong companies or is it just not that common to attend conferences?&#8221;</em>. I&#8217;ve worked as a developer for over six years and as yet I&#8217;ve never had the opportunity to attend a single conference. I <em>thought</em> I might be alone in this, but I&#8217;ve spoken to a large number of developers who are in exactly the same position, some of whom have worked in the industry far longer than I have.</p>
<p>Having worked for small companies in the past, I can fully understand the problems associated with sending developers to conferences. Sending one developer doesn&#8217;t cost a vast amount of money, but if all your developers want to go the money really does start to mount up. After the issue of cost, you then have to factor in the lost development time, not only for the conference but travelling to and from the event as well. The various costs to the business can soon become very prohibitive.</p>
<p>Back in January of this year, I decided that I would make sure I attended a conference this year, and decided I would just pay for it myself. I wanted to see if conferences really are worth the money. After months of discussing it on Spring Forums, I had the pleasure of attending <a href="http://www.springone.com/">SpringOne</a> in June. The conference, hotel, travel and other costs came in at around £800 (€1200 or US$1600) in total. I also decided to take a weeks holiday from work to make the most of my trip.<br />
<span id="more-86"></span><br />
The whole trip turned out to be a great experience. I met up with a number of people I had chatted to on various forums, and also lots of other random developers I met in the hotel. We discussed all aspects of software development late into the night, and I also learnt a great deal about a whole range of subjects. We traded lots of horror stories, and I also got to hear about the new exciting projects people were working on. It was great to meet like minded people who were willing to share information and take part in interesting discussions!</p>
<p>Once the conference started, it was a packed three days of <a href="http://www.springone.com/display/SpringOne07/Conference">presentations</a> and <a href="http://www.springone.com/display/SpringOne07/BOFs">discussions</a>. There were a wide array of presentations running, so there wasn&#8217;t a single time I found myself with nothing to do. The conference demanded various levels of ability, so I was able to attend both beginners and advanced presentations as required. I heard a huge amount of information from experts in their field. I was able to chat to numerous developers who&#8217;s articles and books I had read, and had the opportunity to find out more about the subject from the original author.</p>
<p>So the big question, was it all worth it? Was it <strong>really</strong> worth the £800 price tag? As an experience, I&#8217;d have to say yes, I really had a great time! I learnt a huge amount both inside and outside of the conference. I learnt about new techniques and technologies, some of which I put directly into use when I returned from the conference. I met a great bunch of people, and I heard some really interesting discussions and insights. I met a <a href="http://www.springone.com/display/SpringOne07/Speakers">number</a> of well known speakers and authors, and got to ask some of the questions that came into my head when I originally read their book(s). The benefits of attending the conference have been numerous, both for me personally but also in my day-to-day work. I came back from the conference with lots of ideas and enthusiasm to try them out. I genuinely learnt a great deal in a short space of time.</p>
<p>So would I do it again? This is a much harder question to answer. I would <strong>love</strong> to attend another conference, and I may indeed try to attend another next year (<a href="http://qcon.infoq.com/london-2007/conference/">QCon</a>, <a href="http://www.javapolis.com/">JavaPolis</a>, <a href="http://www.springone.com/">SpringOne</a>). The two biggest problems are obviously the cost of the event and the use of holidays. If your company is willing to pay for the event and/or let you have time off to go, then it&#8217;s obviously worth going. Personally, I&#8217;d jump at the chance. As a one off experience, I could justify paying for the conference and taking the holidays, but as a regular event it&#8217;s much harder to justify.</p>
<p><a href="http://www.parleys.com/display/PARLEYS/Home">Parleys</a> does a great job of sharing lots of presentations, some of which I actually attended. JavaOne and SpringOne also allow you to view and download the presentation slides. Eight hundred pounds might possibly be better spent attending training sessions or achieving certification. The various forums out there, allow you to have regular contact with a huge number of developers from all over the world. Most authors have mailing lists where you can discuss the book with them and with other readers. Lots of the conference experiences can be achieved in some way without actually even attending. However, for me it&#8217;s just not the same as being there.</p>
<p>If you still can&#8217;t persuade your company to pay for you to attend a conference, there are a few of ways to potentially reducing the cost. Some JUGs have discounted entry to conferences and are also allocated a number of free passes. It might be worth checking your local area to see if there is a JUG near you. Lots of the conferences have an early bird discount as well, so if you book straight away you can save yourself some money. I also collected quite a number of business cards from other attendees, so it&#8217;s a great place to get some free publicity for your company. If your boss still isn&#8217;t convinced, work really hard and become a <a href="https://java-champions.dev.java.net/">Java champion</a> or better yet a conference speaker. That should get you free entry to lots of conferences <img src='http://69.89.31.94/~pramatrc/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>Failing that, if you really want to attend a conference, you might just have to put your hand in your pocket and pay for it yourself. In my humble opinion, it didn&#8217;t feel like money down the drain, it was more an investment in myself.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pramatr.com/blog/2008/09/10/are-conferences-really-worth-the-money/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Spring Framework: Where Can I Find Examples And Resources?</title>
		<link>http://www.pramatr.com/blog/2008/09/03/spring-framework-where-can-i-find-examples-and-resources/</link>
		<comments>http://www.pramatr.com/blog/2008/09/03/spring-framework-where-can-i-find-examples-and-resources/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 21:00:00 +0000</pubDate>
		<dc:creator>pramatr</dc:creator>
				<category><![CDATA[Spring]]></category>
		<category><![CDATA[Examples]]></category>
		<category><![CDATA[Resources]]></category>

		<guid isPermaLink="false">http://pramatr.com/2007/09/03/spring-framework-where-can-i-find-examples-and-resources/</guid>
		<description><![CDATA[When ever I&#8217;m working with Spring, one of the most common questions I get asked is &#8220;where can I find good quality examples and resources?&#8221; I hate to disappoint people that I have some secret stash of information, but I get everything I need from the same places as everyone else! Here&#8217;s a brief overview [...]]]></description>
			<content:encoded><![CDATA[<p>When ever I&#8217;m working with Spring, one of the most common questions I get asked is <em>&#8220;where can I find good quality examples and resources?&#8221;</em> I hate to disappoint people that I have some secret stash of information, but I get everything I need from the same places as everyone else! Here&#8217;s a brief overview of the places I visit:</p>
<ol>
<li><a href="http://static.springframework.org/spring/docs/2.0.x/reference/">Spring Framework reference documentation</a> &#8211; I&#8217;ve found the reference manual to be the best source of information on the framework. Anytime I have a question, the first place I look is here! It&#8217;s constantly updated, and it contains lots of recommendations and best practices from the Spring development team. What better recommendations can you have then the people that wrote it!</li>
<li><a href="http://forum.springframework.org/">Spring Framework support forum</a> &#8211; If you&#8217;re still left with questions after looking through the reference documentation, the Spring support forum provides a <strong>very</strong> active and friendly community. There are thousands of answers already on there, so it really pays to do a quick search before you post. If you do post a question make sure you do it the <a href="http://catb.org/~esr/faqs/smart-questions.html">smart</a> way.</li>
<li><a href="http://blog.springsource.com/">Spring Source Team Blog</a> &#8211; Spring from the source. What better place to get information and updates on what the Spring development team are doing.</li>
<li><a href="http://static.springframework.org/spring/docs/2.0.x/api/">Spring Framework Javadoc</a> &#8211; If you want to find details on the API of the Spring classes, the comprehensive JavaDoc is the place to go.</li>
<li><a href="http://www.springhub.com/">Spring Hub</a> &#8211; An independent site containing lots of links and resources related to Spring.</li>
<li><a href="http://www.springframework.org/support">Spring Framework JIRA</a> &#8211; If you think you&#8217;ve found a bug or want to propose an enhancement, JIRA is the place to go.</li>
<li><a href="http://sourceforge.net/mail/?group_id=73357">Spring Framework Mailing List</a> &#8211; If you want to follow the progress of Spring development, you can view the mailing list here or even subscribe.</li>
<li>Sample Applications &#8211; Spring ships with a number of excellent sample applications. Look through them, play with them and understand them. Many people use these examples as a base for their applications, they are an excellent starting point.</li>
<li>Source code &#8211; One of the most over looked resources that Spring has to offer is it&#8217;s source code. It&#8217;s well structured, well written and easy to follow. It&#8217;s also a great place to get answers. The source code for the unit tests is also included with the release. What more information could you be looking for?</li>
<li><a href="http://www.springframework.org/bookreview">Spring Books</a> &#8211; If you are still looking for more information, there are a wide selection of books available. There are several existing threads on Spring forum that discuss the various books and their relative merits.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.pramatr.com/blog/2008/09/03/spring-framework-where-can-i-find-examples-and-resources/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spring JdbcTemplate: The Phantom Performance Problem</title>
		<link>http://www.pramatr.com/blog/2008/08/19/spring-jdbctemplate-the-phantom-performance-problem/</link>
		<comments>http://www.pramatr.com/blog/2008/08/19/spring-jdbctemplate-the-phantom-performance-problem/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 15:52:00 +0000</pubDate>
		<dc:creator>pramatr</dc:creator>
				<category><![CDATA[Spring]]></category>
		<category><![CDATA[Connection Pool]]></category>
		<category><![CDATA[Jdbc]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Transactions]]></category>

		<guid isPermaLink="false">http://pramatr.com/2007/08/19/spring-jdbctemplate-the-phantom-performance-problem/</guid>
		<description><![CDATA[Over the past few years there have been numerous posts on Spring Forum regarding the performance of JdbcTemplate. The majority of these are complaining about poor performance of JdbcTemplate in comparison to pure Jdbc. I thought this topic had been done to death already, but a friend of mine told me his developers were having [...]]]></description>
			<content:encoded><![CDATA[<p>Over the past few years there have been numerous posts on <a href="http://forum.springframework.org/">Spring Forum</a> regarding the performance of <a href="http://www.springframework.org/docs/api/org/springframework/jdbc/core/JdbcTemplate.html">JdbcTemplate</a>. The majority of these are complaining about poor performance of JdbcTemplate in comparison to pure Jdbc. I thought this topic had been done to death already, but a friend of mine told me his developers were having performance problems with JdbcTemplate as recently as last week. They had switched back to Jdbc after some performance comparisons had proven JdbcTemplate was significantly slower.</p>
<p>So what makes JdbcTemplate so much slower than pure Jdbc? In a word&#8230;&#8230;.. nothing. JdbcTemplate does a great job of removing the try/catch/finally/try/catch code we used to write with Jdbc, but under the covers it&#8217;s just doing the same old stuff we used to do. It&#8217;s getting hold of a <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/sql/Connection.html">connection</a>, executing a <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/sql/PreparedStatement.html">statement</a>, possibly mapping a <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/sql/ResultSet.html">result set</a> to an object, converting any exceptions for us and releasing the connection. That&#8217;s pretty much it, it&#8217;s a thin wrapper around Jdbc that makes it usable in the real world.</p>
<p>So why do people report performance problems with JdbcTemplate? I took the opportunity to review the comparison that had reported such terrible performance compared to Jdbc. After a couple of minutes reviewing the comparison it was quite obvious it was fatally flawed, not only was it configured differently, it wasn&#8217;t testing the same thing. Looking at the comparisons that have been posted in the past on Spring Forum, they typically suffer from the same problems. The most common is they generally don&#8217;t perform a <a href="http://www.ise5-14.org.uk/Prim3/New_Guidelines/Investigations/Fair_test.htm">fair test</a>. Lets look at the typical problems the comparisons face before seeing the comparison results once the problems were fixed.<br />
<span id="more-81"></span></p>
<ol>
<li>Connection Pool vs Single Connection</li>
<p>One test uses a <a href="http://sourceforge.net/projects/c3p0">connection pool</a> and the other will acquire a new <a href="http://www.springframework.org/docs/api/org/springframework/jdbc/datasource/DriverManagerDataSource.html">connection</a> every time a statement is executed. This can have differing effects on the test results depending on the initial pool size. If this is set to a high value then typically the connection pool tests will perform slower. Either way, use the same data source for both tests with the same settings.</p>
<li>Transactions</li>
<p>One test uses transactions and the other executes non-transactionally, or the transactions are applied at different levels. There&#8217;s no point wrapping each query execution in a transaction in one test and in the other test applying it to the <a href="http://www.martinfowler.com/eaaCatalog/serviceLayer.html">service layer</a>. This was actually one of the problems with the original performance comparison. The transactions were applied at the service layer in one test and the <a href="http://java.sun.com/blueprints/patterns/DAO.html">DAO</a> in the other.</p>
<li>Jdbc <a href="http://www.springframework.org/docs/api/org/springframework/jdbc/core/RowMapper.html">RowMapper</a> equivalent doesn&#8217;t do anything</li>
<p>This is the most common problem I&#8217;ve seen. Although the pure Jdbc version of the code executes a query, the result set is ignored as the results are not processed and mapped into the object representations. This obviously shows a massive improvement over JdbcTemplate as it&#8217;s not actually doing anything. If it isn&#8217;t processing the results, it&#8217;s going to be quicker!</p>
<li><a href="http://java.sun.com/j2se/1.5.0/docs/api/java/sql/PreparedStatement.html">Prepared Statements</a> vs String-based queries</li>
<p>Prepared statements are potentially going to be more efficient than string-based queries (depending on platform). Initially the prepared statement is going to be more expensive to create, but if it&#8217;s reused it should produce improved performance as it should be available from the statement cache.</p>
<li><a href="http://www.onjava.com/pub/a/onjava/excerpt/javaentnut_2/index3.html?page=">Batch Statements</a></li>
<p>One test uses batched prepared statements and the other executes a separate prepared statement.</p>
<li>Creating a new <a href="http://www.springframework.org/docs/api/org/springframework/context/ApplicationContext.html">ApplicationContext</a> for every test run</li>
<p>Although this is the least common problem, it was actually one of the problems in the aforementioned comparison. If one test uses Spring and the other doesn&#8217;t, either create the ApplicationContext outside of the test or at least ensure it&#8217;s construction isn&#8217;t included in the time taken to complete the test.
</ol>
<p>Let&#8217;s have a look at the performance comparison that was discussed at the beginning of the blog and also the <strong>real</strong> statistics it produced. The test consisted of creating, updating, deleting and retrieving a number of users. In this example the number of users was set to one thousand, and the test was run one hundred times to give an average time for each operation. For the sake of brevity I&#8217;ve only included the code here for retrieving and updating the users, the code for creating and deleting them however followed exactly the same pattern.</p>
<p>This is the pure Jdbc code that retrieves all the users and update the user&#8217;s password.</p>
<blockquote><pre><span style="font-size:small;"><strong>public</strong> <span style="color:#2040a0;">List</span><span style="color:#4444ff;">&lt;</span><span style="color:#2040a0;">User</span><span style="color:#4444ff;">&gt;</span> <span style="color:#2040a0;">getUsers</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
	<strong>return</strong> <span style="color:#2040a0;">jdbcTemplate</span>.<span style="color:#2040a0;">query</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"SELECT * FROM user_details"</span>, <strong>new</strong> <span style="color:#2040a0;">RowMapper</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
		<strong>public</strong> <span style="color:#2040a0;">Object</span> <span style="color:#2040a0;">mapRow</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">ResultSet</span> <span style="color:#2040a0;">rs</span>, <strong>int</strong> <span style="color:#2040a0;">rowNum</span><span style="color:#4444ff;"><strong>)</strong></span> <strong>throws</strong> <span style="color:#2040a0;">SQLException</span> <span style="color:#4444ff;"><strong>{</strong></span>
			<span style="color:#2040a0;">String</span> <span style="color:#2040a0;">username</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">rs</span>.<span style="color:#2040a0;">getString</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"username"</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
			<span style="color:#2040a0;">String</span> <span style="color:#2040a0;">password</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">rs</span>.<span style="color:#2040a0;">getString</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"password"</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
			<strong>return</strong> <strong>new</strong> <span style="color:#2040a0;">User</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">username</span>, <span style="color:#2040a0;">password</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
		<span style="color:#4444ff;"><strong>}</strong></span>
	<span style="color:#4444ff;"><strong>}</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
<span style="color:#4444ff;"><strong>}</strong></span>

<strong>public</strong> <strong>void</strong> <span style="color:#2040a0;">updateUsers</span><span style="color:#4444ff;"><strong>(</strong></span><strong>final</strong> <span style="color:#2040a0;">List</span><span style="color:#4444ff;">&lt;</span><span style="color:#2040a0;">User</span><span style="color:#4444ff;">&gt;</span> <span style="color:#2040a0;">users</span><span style="color:#4444ff;"><strong>)</strong></span> <strong>throws</strong> <span style="color:#2040a0;">Exception</span> <span style="color:#4444ff;"><strong>{</strong></span>
	<strong>this</strong>.<span style="color:#2040a0;">jdbcTemplate</span>.<span style="color:#2040a0;">batchUpdate</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#008000;">"UPDATE user_details SET password = ? WHERE username = ?"</span>,
				<strong>new</strong> <span style="color:#2040a0;">BatchPreparedStatementSetter</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
		<strong>public</strong> <strong>void</strong> <span style="color:#2040a0;">setValues</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">PreparedStatement</span> <span style="color:#2040a0;">ps</span>, <strong>int</strong> <span style="color:#2040a0;">i</span><span style="color:#4444ff;"><strong>)</strong></span> <strong>throws</strong> <span style="color:#2040a0;">SQLException</span> <span style="color:#4444ff;"><strong>{</strong></span>
			<span style="color:#2040a0;">User</span> <span style="color:#2040a0;">user</span> <span style="color:#4444ff;">=</span> <span style="color:#2040a0;">users</span>.<span style="color:#2040a0;">get</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">i</span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
			<span style="color:#2040a0;">ps</span>.<span style="color:#2040a0;">setString</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#ff0000;">1</span>, <span style="color:#2040a0;">PasswordObfuscator</span>.<span style="color:#2040a0;">obfuscate</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#2040a0;">user</span>.<span style="color:#2040a0;">getPassword</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
			<span style="color:#2040a0;">ps</span>.<span style="color:#2040a0;">setString</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#ff0000;">2</span>, <span style="color:#2040a0;">user</span>.<span style="color:#2040a0;">getUsername</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
		<span style="color:#4444ff;"><strong>}</strong></span>

		<strong>public</strong> <strong>int</strong> <span style="color:#2040a0;">getBatchSize</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span> <span style="color:#4444ff;"><strong>{</strong></span>
			<strong>return</strong> <span style="color:#2040a0;">users</span>.<span style="color:#2040a0;">size</span><span style="color:#4444ff;"><strong>(</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
		<span style="color:#4444ff;"><strong>}</strong></span>
	<span style="color:#4444ff;"><strong>}</strong></span><span style="color:#4444ff;"><strong>)</strong></span><span style="color:#4444ff;">;</span>
<span style="color:#4444ff;"><strong>}</strong></span></span></pre>
</blockquote>
<p>And finally let&#8217;s have a look at those all important numbers.</p>
<p>Jdbc DAO<br />
insert: <strong>360ms</strong>, fetch: <strong>7ms</strong>, update: <strong>276ms</strong>, delete: <strong>136ms</strong></p>
<p>JdbcTemplate DAO<br />
insert: <strong>363ms</strong>, fetch: <strong>5ms</strong>, update: <strong>278ms</strong>, delete: <strong>133ms</strong></p>
<p>Transactional Jdbc DAO<br />
insert: <strong>963ms</strong>, fetch: <strong>6ms</strong>, update: <strong>276ms</strong>, delete: <strong>131ms</strong></p>
<p>Transactional JdbcTemplate DAO<br />
insert: <strong>948ms</strong>, fetch: <strong>6ms</strong>, update: <strong>274ms</strong>, delete: <strong>131ms</strong></p>
<p>As expected there&#8217;s really not that much in it. Once the issues were fixed in the original comparison they come out pretty much the same. JdbcTemplate doesn&#8217;t have the performance problems the original comparison reported and actually shows pretty much the same performance as pure Jdbc. So the moral of the story&#8230;&#8230;. if you are doing a comparison make sure you are comparing the same things and most importantly whatever you tweak, make it a <a href="http://www.ise5-14.org.uk/Prim3/New_Guidelines/Investigations/Fair_test.htm">fair test</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pramatr.com/blog/2008/08/19/spring-jdbctemplate-the-phantom-performance-problem/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
