<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace Site Server v5.11.5 (http://www.squarespace.com/) on Wed, 08 Sep 2010 05:40:48 GMT--><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"><title>Rimple on Tech</title><subtitle>Rimple on Tech</subtitle><id>http://www.rimple.com/tech/</id><link rel="alternate" type="application/xhtml+xml" href="http://www.rimple.com/tech/"/><link rel="self" type="application/atom+xml" href="http://www.rimple.com/tech/atom.xml"/><updated>2010-09-04T16:21:40Z</updated><generator uri="http://www.squarespace.com/" version="Squarespace Site Server v5.11.5 (http://www.squarespace.com/)">Squarespace</generator><entry><title>Living on the Roo "edge" w/git</title><category term="Spring Roo"/><category term="SpringSource Roo"/><category term="chariot-news"/><id>http://www.rimple.com/tech/2010/9/4/living-on-the-roo-edge-wgit.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/9/4/living-on-the-roo-edge-wgit.html"/><author><name>Ken Rimple</name></author><published>2010-09-04T16:06:43Z</published><updated>2010-09-04T16:06:43Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><span class="full-image-float-right ssNonEditable"><span><img style="width: 100px;" src="http://www.rimple.com/storage/post-images/shut-in-ken.jpg?__SQUARESPACE_CACHEVERSION=1283617285960" alt="" /></span><span class="thumbnail-caption" style="width: 100px;">Yep, I'm officially a writer - look I even have over 40 reading glasses on!</span></span>Writing a book against a moving target is, well, moving. &nbsp;Sometimes I just need to work with the latest Roo from git, to see where it's going. &nbsp;For a while, there were incompatibilities in the STS Roo shell support that kept me from doing this, but with a little fudging around, I figured out how to do it for the unreleased 1.1.0.M4 line.</p>
<p>These instructions assume you have a working roo-dev shell, and are able to mvn install and use GIT. &nbsp;Once you follow the instructions, you'll potentially have a working STS install that works against the GIT build of Roo, so you can watch progress between builds.</p>
<p>Do you need this? Well, no, maybe not. &nbsp;</p>
<p>I do, since what I'm writing a book on depends on a somewhat rapidly evolving framework. &nbsp;Speaking of the book, we are releasing another MEAP soon that will add another chapter, and also fix a lot of the wording, typos and other issues from the first four chapters. &nbsp;Look for that soon, and thanks to everyone who is reading those MEAPs and participating in the review process. &nbsp;We truly value you!.</p>
<h3>Steps</h3>
<ul>
<li>First, get the latest code by using git pull</li>
<li>Make sure it builds, using mvn install</li>
<li>Make an assembly of Roo - this creates a zip install that you can unzip so STS can see it. &nbsp;Do it this way: &nbsp;mvn assembly:assembly</li>
<li>Take the file it creates in ./target/org.springframework.roo.root-1.1.0.M4.zip and move it somewhere, unzip it. &nbsp;You now have a spring-roo-1.1.0.M4 directory with a distribution of the GIT code head. &nbsp;YAY!</li>
<li>Decide whether you want to use this version on the command line as your regular roo. &nbsp;I don't, I still use roo-dev. &nbsp;</li>
<li>In STS, make sure you're using an external maven build - go to STS -&gt; Preferences, search for Maven, add an external installation for 2.2.1 (which you've downloaded by now, I hope)</li>
<li>Also in STS, go to STS -&gt; Preferences, search for Roo, and add this new 1.1.0.M4 roo installation, making it the default (don't forget to switch back if you don't like what you see).</li>
<li>Open your 1.1.0.M4 project, and if it doesn't automatically configure as a Roo project, just add Roo project nature and if you're still getting trouble, add the AspectJ Tooling feature too (from the Spring right-click project menu).</li>
</ul>
<p>Sorry this is jotted down so hastily. &nbsp;This is more of a note for me than everyone else, but I figured others could benefit.</p>
<p>One other note - if you somehow had a custom maven repo that you configured, check your Maven settings carefully. &nbsp;I had to make sure my Maven install was correct. &nbsp;Also, if you forget to mvn install the Roo dev build, it won't install the JAR files into your repository and you won't be able to build your projects. &nbsp;</p>
<p>Enjoy!</p>
<p>&nbsp;</p>]]></content></entry><entry><title>Spring JUnit Tests not Rolling Back? It may not be you...</title><category term="Hibernate"/><category term="JUnit"/><category term="Tutorial"/><category term="chariot-news"/><category term="database"/><category term="spring"/><category term="testing"/><id>http://www.rimple.com/tech/2010/8/29/spring-junit-tests-not-rolling-back-it-may-not-be-you.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/8/29/spring-junit-tests-not-rolling-back-it-may-not-be-you.html"/><author><name>Ken Rimple</name></author><published>2010-08-29T15:53:29Z</published><updated>2010-08-29T15:53:29Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><em>Plug/Disclaimer! I'm teaching a <a href="http://www.chariotsolutions.com/education/courses/hibernate_with_spring" target="_blank">Hibernate with Spring</a> course in September, and while preparing for the course I came up with this tidbit.  I hope you enjoy it.</em></p>
<p>Here's a little tip for you Spring users who are using MySQL. &nbsp;If you just installed MySQL with the defaults, you may find that Spring's @ContextConfiguration and @RunWith(SpringJUnit4Runner.class) annotations might not work for you.</p>
<pre class="brush: java">
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.
       transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

@ContextConfiguration(locations=
   {"classpath:/META-INF/spring/applicationContext.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(defaultRollback=true)
public class CourseIntegrationTest {

  @Autowired
  private SessionFactory sessionFactory;
  
  
  @Test
  @Transactional
  public void testCreateCourse() {
    Session session = sessionFactory.getCurrentSession();
    Course course = new Course();
    course.setCost(new BigDecimal("1000.00"));
    course.setDescription("Basketweaving");
    course.setStartDate(new Date());
    
    session.save(course);
    
    // now, we get and check
    session.flush();
    
    Assert.assertNotNull(course.getId());   
    
  }
  
}
</pre>

<h3>The Problem...</h3>
<p>The default behavior of Spring when running integration tests like this is to roll back the transaction. So, you go ahead and execute the test, and hope that it rolls back the row.  But, in fact, it might not - you might see the row in the database.  Why?</p>
<p>The answer lies in whether you've installed and configured the InnoDB engine in MySQL.  What is InnoDB?  It's a transactional storage engine that ships with MySQL binaries as of 5.1 and higher. Here is a good <a href="http://en.wikipedia.org/wiki/InnoDB" target="_blank">wikipedia article on InnoDB</a> for further reading.  You can tell whether it is installed by executing the following SQL as the 'root' MySQL user: (I've removed the "comment" field so it fits on my blog page)</p>
<pre class="brush: text">

+------------+---------+--------------+------+------------+
| Engine     | Support | Transactions | XA   | Savepoints |
+------------+---------+----------------------------------+
| CSV        | YES     | NO           | NO   | NO         |
| MRG_MYISAM | YES     | NO           | NO   | NO         |
| MEMORY     | YES     | NO           | NO   | NO         |
| MyISAM     | DEFAULT | NO           | NO   | NO         |
+------------+---------+--------------+------+------------+
</pre>
<p>In the case above, I haven't yet configured InnoDB - MyISAM is the default engine, which is also non-transactional.  Since MySQL can have several installed engines, and one is the default, setting the wrong default (as well as not installing a transactional engine) can be a problem!</p>
<p>When you create tables, you can specify the engine they use, otherwise they get the default.  I found a GREAT article about <a href="http://www.insaneprogramming.be/?p=200" target="_blank">verifying your Spring JPA MySQL tables</a> to make sure they use a transactional (InnoDB) data store.  Since we're geeking out, you can also run this command in MySQL against your table to see what settings it has (many more columns come back than the ones I'm showing):</p>
<pre class="brush: text">
mysql> show table status;
+--------+--------+---------+------------+------+----------------+
| Name   | Engine | Version | Row_format | Rows | Avg_row_length |
+--------+--------+---------+------------+------+----------------+
| Course | MyISAM |      10 | Compact    |    1 |          16384 |
+--------+--------+---------+------------+------+----------------+
</pre>
<p>Run your JUnit Spring integration tests against a table with this engine, and you'll see that rollbacks are ignored, even though Spring shows that they are sent.  Here is what Spring shows us when we run the test, which would lead you to believe that everything is ok, until you look at the data in the table:</p>
<pre class="brush: text">
Fetching JDBC Connection from DataSource
Returning JDBC Connection to DataSource
Creating new transaction with name [testCreateCourse]: 
  PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
Opened new Session ... for Hibernate transaction
Preparing JDBC Connection of Hibernate Session ...
Exposing Hibernate transaction as JDBC transaction 
   [jdbc:mysql://localhost:3306/hibernate_sandbox, 
   UserName=root@localhost, MySQL-AB JDBC Driver]
Hibernate: 
    insert 
    into
        Course
        (cost, description, startDate) 
    values
        (?, ?, ?)
binding '1000.00' to parameter: 1
binding 'Basketweaving' to parameter: 2
binding '29 August 2010' to parameter: 3
Triggering beforeCompletion synchronization
Initiating transaction rollback
Rolling back Hibernate transaction on Session ...
Triggering afterCompletion synchronization
Closing Hibernate Session ... after transaction
Closing Hibernate Session
Closing Hibernate SessionFactory
</pre>

<p><em>Incidentally, here is my log4j.properties file for getting all of that nice log output:</em></p>
<pre class="brush: text">
# suppress everything else
log4j.logger.org.springframework=error
log4j.logger.org.hibernate=error

# log field bindings
log4j.logger.org.hibernate.type=trace

# log transactions
log4j.logger.org.springframework.jdbc.datasource=trace
log4j.logger.org.springframework.orm.hibernate3=trace 
</pre>
<p>... and my Hibernate settings from within my AnnotationSessionFactoryBean...</p>
<pre class="brush: xml">
&lt;property name=&quot;hibernateProperties&quot;&gt;
  &lt;value&gt;
    hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
    hibernate.hbm2ddl.auto=update
    hibernate.show_sql=true
    hibernate.format_sql=true
  &lt;/value&gt;
&lt;/property&gt;
</pre>
<p>Ok, so obviously for a serious application involving more than one SQL statement at a time, this is seriously inadequate.  So, let's fix it!</p>
<h3>Installing InnoDB</h3>
<p>I'm using a Mac, so your mileage for these instructions will vary, and you'll have to have a passing familiarity with the command line.  First, create a my.cnf file (or edit the existing one).  Mine is located in /etc/my.cnf, but yours may live in /usr/local/mysql/data or in another place.  I have added the following settings to my file, taken from a few blog entries:</p>
<pre class="brush: text;font-size: 8pt;">
[mysqld]
default-storage-engine=InnoDB
innodb_data_home_dir=/usr/local/mysql/data
innodb_data_file_path=ibdata-new:10M:autoextend
innodb_buffer_pool_size=256M
innodb_additional_mem_pool_size=20M
innodb_log_file_size=64M
innodb_log_buffer_size=8M
innodb_flush_log_at_trx_commit=1
</pre>
<p>Now, to install this file, you need to shutdown and start up MySQL.  I use the following commands from OS X:</p>
<pre class="brush: shell">
sudo mysqladmin shutdown
sudo mysqld_safe --console & 
sudo cat /usr/local/mysql/data/yourservername.err
</pre>

<h3>Verifying the Installation</h3>
<p>Now, to verify that everything is configured correctly, check the same <pre>show engines</pre> command again as the MySQL root user:</p>

<pre class="brush: sql">
mysql> show engines;
+------------+---------+--------------+------+------------+
| Engine     | Support | Transactions | XA   | Savepoints |
+------------+---------+--------------+------+------------+
| CSV        | YES     | NO           | NO   | NO         |
| MRG_MYISAM | YES     | NO           | NO   | NO         |
| MEMORY     | YES     | NO           | NO   | NO         |
| InnoDB     | DEFAULT | YES          | YES  | YES        |
| MyISAM     | YES     | NO           | NO   | NO         |
+------------+---------+--------------+------+------------+
5 rows in set (0.01 sec)

</pre>

<P>If all is well, you now have InnoDB, and it's the default engine.  Try the test, and see if the rows are rolled back.  <b>Important: you may have to drop or modify the table to make it use InnoDB.</b>  There is a simple SQL command to modify it: </p>
<pre class="brush: sql">

mysql> alter table Course engine=InnoDB;
Query OK, 0 rows affected (0.11 sec)
Records: 0  Duplicates: 0  Warnings: 0
</pre>

<p>If you get any warnings, just type <pre>show warnings</pre> and you'll get a message.</p>
<p>That's it.  I hope this helps someone who is wrestling with MySQL databases and Hibernate transactions.  I know I have had trouble with this when preparing the Hibernate section of my book, Roo in Action.</p>]]></content></entry><entry><title>Progress on Roo in Action</title><id>http://www.rimple.com/tech/2010/7/30/progress-on-roo-in-action.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/7/30/progress-on-roo-in-action.html"/><author><name>Ken Rimple</name></author><published>2010-07-30T15:34:49Z</published><updated>2010-07-30T15:34:49Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>We've been ploughing ahead with the Spring Roo in Action book over the past few months. &nbsp;For those of you who bought the MEAP, participated in the 1/3 review, and otherwise gave us feedback so far, THANK YOU THANK YOU THANK YOU!</p>
<p>Currently I'm working on the web chapters of the book. &nbsp;It turns out that Spring Roo has a lot of interesting approaches for dealing with HTML content. &nbsp;Things like using XML-parseable JSP pages (called JSPX pages), generation of REST-friendly tags for forms (the form:update tag generates the proper form fields and URL to process PUTs for example).</p>
<p>So I am going to be pretty consumed in writing the two web chapters and also taking all of your VERY helpful feedback into Chapters 1-4. &nbsp;Gordon is working on other chapters as well, focusing more on integration services, so keep up with him over at <a class="offsite-link-inline" href="http://www.gordondickens.com" target="_blank">GordonDickens.com</a>. &nbsp;We were kicking around doing a webinar or seminar online soon, so if you have any interest let us know via the @RooInAction twitter user.</p>
<p>Thanks again, and we'll update you soon.</p>]]></content></entry><entry><title>Spring Roo In Action MEAP Now Available</title><category term="Announcements"/><category term="Roo in Action"/><category term="Spring Roo"/><id>http://www.rimple.com/tech/2010/7/10/spring-roo-in-action-meap-now-available.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/7/10/spring-roo-in-action-meap-now-available.html"/><author><name>Ken Rimple</name></author><published>2010-07-11T00:35:58Z</published><updated>2010-07-11T00:35:58Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><span class="thumbnail-image-float-left ssNonEditable"><span><a href="http://www.manning.com/dickens/dickens_cover150.jpg" target="_blank"><img src="http://www.manning.com/dickens/dickens_cover150.jpg?__SQUARESPACE_CACHEVERSION=1278808767703" alt="" /></a></span><span class="thumbnail-caption" style="width: 150px;">Roo in Action MEAP</span></span>We are proud to announce the opening of the Manning Author forum, and the offering of the first MEAP, for Spring Roo in Action.  You can find out all of the information, including accessing a free download of Chapter 1, by visiting the <a class="offsite-link-inline" href="http://www.manning.com/dickens" target="_blank">MEAP website</a>.</p>
<p>The first two Chapters delivered are Chapter 1, which introduces Roo, and Chapter 3, an overview of database persistence, from setup to implementation.  In Chapter 3 we get into topics such as Bean Validation, testing using the Integration Test framework, use of the entity APIs, and more.</p>
<p>The <a class="offsite-link-inline" href="http://www.manning-sandbox.com/forum.jspa?forumID=682" target="_blank">Author Forum</a> is a place where you can leave feedback. We'd love to hear your thoughts as we go along.  Remember, this is our first MEAP, so things may not be 100% in place, and chapters will be enhanced with more detail in updated deliveries.</p>
<p> </p>]]></content></entry><entry><title>RESTing with Roo - adding Content Negotiation and REST in two easy steps (well, kinda)</title><category term="REST"/><category term="Roo"/><category term="groovy"/><category term="spring"/><category term="spring"/><category term="tips"/><id>http://www.rimple.com/tech/2010/7/1/resting-with-roo-adding-content-negotiation-and-rest-in-two.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/7/1/resting-with-roo-adding-content-negotiation-and-rest-in-two.html"/><author><name>Ken Rimple</name></author><published>2010-07-01T09:12:30Z</published><updated>2010-07-01T09:12:30Z</updated><content type="html" xml:lang="en-US"><![CDATA[<em>Note:  I don't know if I'm approaching this right...  At least on Firefox, it seems to work.  But on Safari, it fails.  I'll revisit this soon.  </em>

<p>Ok, here's another stream-of-consciousness post on REST support from a Roo application.  I'm working on various research for our [PLUG] <a href="http://www.chariotsolutions.com/education/courses/core-spring" target="_blank" title="Register for the Core Spring Courses at Chariot Solutions in Philadelphia, PA" class="offsite-link-inline">SpringSource Core Spring</a> training classes, always attempting to get better examples so I can do more than just show the slides and labs, and I decided to use Roo to build myself a REST server.</p>

<p>Easy, I thought...  Roo has RESTful URLs, and so I just have to set up the right configuration.</p>

<p>Kind of.</p>

<p>The basic steps to REST-enable a web app in Spring MVC using the built-in REST support are:</p>
<ol>
	<li>Install the proper JARs for your Marshallers</li>
	<li>Install the ContentNegotiatingViewResolver</li>
</ol>

<p>I had a bit of a hiccup figuring this out.  Thanks to a great pair of threads on SpringSource's forums, here and here, I realized I had configured a few things wrong. </p>

<h3>Setting up the example</h3>

<p>Here's my Spring Roo log file, which you can cut and paste into a text file and then do a "roo script filename" command to set up for you.</p>

<pre class="brush: plain;">project --topLevelPackage rest.demo --projectName spring-mvc-rest-demo
persistence setup --provider HIBERNATE --database HYPERSONIC_PERSISTENT 
entity --class ~.db.Customer
field string firstname
field string lastname
field date --fieldName dob --type java.util.Date
field number --fieldName discount --type java.math.BigDecimal --decimalMin 0 --decimalMax 1.0
controller scaffold --entity rest.demo.db.Customer --class rest.demo.web.CustomerController
</pre>

<p>Once you do that, now you're ready for some fun...  </p>

<p>The additional dependencies for your Maven pom.xml file (you'll need to add these to the main dependencies tag section at the end...) (for XML conversion, we're using Castor, which auto-generates XML based on the reflection of JavaBean properties on your bean, and for JSON we're using the Jaskson JSON library.  For this to work, you have to install spring-oxm, which isn't installed in Roo by default - I SMELL PLUGIN...  RACE YA!).</p>

<pre class="brush: xml;">
&lt;dependency&gt;
  &lt;groupId&gt;org.codehaus.jackson&lt;/groupId&gt;
  &lt;artifactId&gt;jackson-mapper-asl&lt;/artifactId&gt;
  &lt;version&gt;1.5.3&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
  &lt;groupId&gt;org.springframework&lt;/groupId&gt;
  &lt;artifactId&gt;spring-oxm&lt;/artifactId&gt;
  &lt;version&gt;${spring.version}&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
  &lt;groupId&gt;org.codehaus.castor&lt;/groupId&gt;
  &lt;artifactId&gt;castor-xml&lt;/artifactId&gt;
  &lt;version&gt;1.3.1&lt;/version&gt;
&lt;/dependency&gt;
</pre>

<p>Now, the Spring webmvc-config.xml file changes.  This file is located in src/main/webapp, 
under the WEB-INF/spring directory, of course.  Add this to the end of the file before the closing
beans tag...</p>

<pre class="brush: xml;">
&lt;bean id=&quot;htmlMediaType&quot; class=&quot;org.springframework.http.MediaType&quot;&gt;
  &lt;constructor-arg value=&quot;text&quot; /&gt;
  &lt;constructor-arg value=&quot;html&quot; /&gt;
&lt;/bean&gt;
&lt;bean
class=&quot;org.springframework.web.servlet.view.ContentNegotiatingViewResolver&quot;&gt;
  &lt;property name=&quot;order&quot; value=&quot;0&quot; /&gt;
  &lt;property name=&quot;defaultContentType&quot;&gt;
    &lt;ref bean=&quot;htmlMediaType&quot; /&gt;
  &lt;/property&gt;
  &lt;property name=&quot;mediaTypes&quot;&gt;
    &lt;map&gt;
      &lt;entry key=&quot;json&quot; value=&quot;application/json&quot; /&gt;
      &lt;entry key=&quot;xml&quot; value=&quot;application/xml&quot; /&gt;
    &lt;/map&gt;
  &lt;/property&gt;
  &lt;property name=&quot;defaultViews&quot;&gt;
    &lt;list&gt;
      &lt;bean
     class=&quot;org.springframework.web.servlet.view.json.MappingJacksonJsonView&quot; /&gt;
      &lt;bean class=&quot;org.springframework.web.servlet.view.xml.MarshallingView&quot;&gt;
        &lt;property name=&quot;marshaller&quot;&gt;
          &lt;bean class=&quot;org.springframework.oxm.castor.CastorMarshaller&quot; /&gt;
        &lt;/property&gt;
      &lt;/bean&gt;
    &lt;/list&gt;
  &lt;/property&gt;

  &lt;property name=&quot;viewResolvers&quot;&gt;
    &lt;ref bean=&quot;tilesViewResolver&quot; /&gt;
  &lt;/property&gt;
&lt;/bean&gt;
</pre>

<p>Next, in the same file, add the order property, setting it to 1, to the instance of the AjaxUrlBasedViewResolver so that
	it looks roughly like this :</p>
<pre class="brush: xml;">
&lt;bean class=&quot;org.springframework.js.ajax.AjaxUrlBasedViewResolver&quot;
  id=&quot;tilesViewResolver&quot;&gt;
  &lt;property name=&quot;order&quot; value=&quot;1&quot; /&gt;
  &lt;property name=&quot;viewClass&quot;
    value=&quot;org.springframework.web.servlet.view.tiles2.TilesView&quot; /&gt;
&lt;/bean&gt;
</pre>

<p>What you're seeing at work here in this setup is the configuration of a default media type of 
	text/html, and a configuration of a first-level view resolver that does content negotiation first.  
	You'll see the order setting was made to make the AjaxBasedViewResolver go first, which threw me,
	but that's an area for more research as I start to dig deeper into the interplay between the various
	view resolvers...  Generally you want the JSP file-based resource view resolver to 
go last, as it is greedy, but Tiles changes that for us a bit.  I am not 100% sure everything works as advertised - for example I need to do some AJAX testing to make sure those calls work.  But for getting REST against a webapp, well, there you have it.</p>
<h3>Testing it!</h3>
<p>Well, that wasn't so much configuration, was it?  I'm experimenting with REST using the Groovy
	<a href="http://groovy.codehaus.org/modules/http-builder/doc/rest.html" target="_blank" title="props to the peeps - RESTClient is pretty darn cool..." class="offsite-link-inline">RESTClient</a> library at the moment (I'm going to use <a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html" target="_blank" title="Spring's REST Template makes it easy to call any REST server from Spring.  But of course you knew that!" class="offsite-link-inline">Spring REST Template</a> in JUnit4 for the class, but also wanted
	something I could script up at a moment's notice and show them how REST works without waiting
	for those compile cycles...)  BTW, I'm on Groovy 1.7.2 (haven't yet upgraded to 1.7.3) and the <code>@Grab</code> line uses Groovy's GRAPE artifact manager to install a grape from the ole' vine (puts it in ~/.groovy/grape/grapes or something)...  WICKED COOL.  Yes, I used my blog to say WICKED COOL.  You can't stop me!</p>
<pre class="brush: groovy">
@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.0' )
import groovyx.net.http.RESTClient

def customers = new RESTClient( 'http://localhost:8008/demo/')
def results = customers.get (path : 'customers',
   headers: [Accept : 'application/json', "Accept-Encoding" : 'gzip,deflate'])

println results.data
</pre>
<p>Switch from JSON to XML, using application/xml as the Accept header, and you'll see it
automatically respond with the appropriate datatype.  Great!  Now, if you use XML, change
from that println statement to this:
<pre class="brush: groovy">
results.data.customer.each { c ->
  println "customer:  $c.id, $c.firstname $c.lastname"
}
</pre>
<p>And if you want to test it on the browser, and see it do content negotation by file extension
instead, just hit:  <code>http://localhost:8080/spring-mvc-rest-demo/customers.xml</code> or <code>http://localhost:8080/spring-mvc-rest-demo/customers.json</code>
to see the REST data, and <code>http://localhost:8080/spring-mvc-rest-demo/customers</code> to see the regular
tiles views.</p>
<p>Enjoy...</p>
<p><em>Oh, and while I'm shilling for my training group at Chariot, please visit our <a href="http://www.chariotsolutions.com/education" target="_blank" title="Our course events calendar." class="offsite-link-inline">course calendar</a> if you are interested in our fall lineup - <a href="http://chariotsolutions.com/education/courses/hibernate_with_spring" target="_blank" title="Hibernate with Spring - learn Hibernate on the Spring Platform from SpringSource training at Chariot" class="offsite-link-inline">Hibernate with Spring</a>, <a href="http://chariotsolutions.com/education/courses/spring_enterprise_integration" target="_blank" title="Learn integration topics such as web services, transactions, jms, REST, Spring Integration and Batch at Chariot in Philadelphia.  Official SpringSource training." class="offsite-link-inline">Spring Enterprise Integration</a>, <a href="http://chariotsolutions.com/education/courses/spring_core" target="_blank" title="Learn the Core Spring Framework with the official SpringSource training course.  Certification voucher included." class="offsite-link-inline">Core Spring</a>, or <a href="http://chariotsolutions.com/education/courses/maven_intro" target="_blank" title="The introductory Sonatype Maven training course.  Learn a lot about Maven from this one-day course." class="offsite-link-inline">Maven Intro</a> and <a href="http://chariotsolutions.com/education/courses/maven_intermediate" target="_blank" title="This training includes an overview of Maven and Repositories, Hudson, plugins, sites, and multi-project POMs.  Very good in-depth course." class="offsite-link-inline">Advanced</a> training.  Thanks, and I'll refrain from using a strange chamois in any of my in-line advertisements...</em></p>]]></content></entry><entry><title>Kickin' Butt with Spring Roo at the command line with Maven shade plugin</title><category term="SpringSource Roo"/><category term="Technologies"/><category term="maven"/><id>http://www.rimple.com/tech/2010/6/24/kickin-butt-with-spring-roo-at-the-command-line-with-maven-s.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/6/24/kickin-butt-with-spring-roo-at-the-command-line-with-maven-s.html"/><author><name>Ken Rimple</name></author><published>2010-06-24T19:11:49Z</published><updated>2010-06-24T19:11:49Z</updated><content type="html" xml:lang="en-US"><![CDATA[<em>Note:  I just noticed, maybe it's something just added in 1.1.0 or later builds, but they have the assembly plugin integrated with the Roo Shell perform command. So you can do <code>perform assembly</code> and actually get an assembled jar with all dependencies.  WOOT.  Anyway, this is still useful for those who want to run Maven headless projects.</em
<p>Let's say you want to use Spring Roo to do persistence work, but you don't need a website. Maybe it's just a utility, something that, say uses iText to generate PDF files, or does some data processing, job execution, or some other headless task.</p>
<p>Spring Roo is built using Maven, and the build target generally start in an initial Roo project by deploying a JAR file, until you add Spring MVC by adding a controller.  In Maven, the output of a given build is generally one thing, (the jar) so running the project might involve downloading a ton of JAR files to add to a very big classpath.  That's a lot of work.</p>
<h3>Alternatives - Maven Packaging Plugins</h3>
<p>There are a number of maven packaging plugins that can assemble a Jar that includes all of your classes and property files from various source Jars.  Several, including the Maven assembly plugin, and the one-jar plugin, didn't work for me out of the gate due to some problems loading some of the SpringSource XML schemas and extender languages.</p>
<p>The challenge is that these special files, META-INF/spring.handlers and META-INF/spring.schemas, are included in each of the extension JARs (like Spring Security, Spring MVC, JMS, etc) so that you can issue commands like this:</p> <pre>&lt;mvc:annotation-driven /&gt;</pre>  <p>These tools generally copy files into a temp directory and then jar it up, so they overwrite these files each time.</p>
<h3>The Shade Plugin</h3>
The <a class="offsite-link-inline" href="http://maven.apache.org/plugins/maven-shade-plugin/index.html" target="_blank">Maven shade plugin</a> has a nice feature called a transformer.  There is a special AppendingTransformer class that can be configured to continue to append data into a file specified in the configuration.  Based on <a class="offsite-link-inline" href="http://www.hagelnx.com/prog/814" target="_blank">this article from Hagel Blog</a>, I added two entries to the plugin configuration (as commented below) to fix the two META-INF files and we were in business.</p>
<p>So, without further adieu, here are the steps to single-jar happiness (at least so far) with Spring Roo and the Maven Shade plugin:</p>

<h3>Step 1: Install the Shade Plugin to your pom.xml file</h3>

<p>Using your STS or favorite editor, go to your maven build file, pom.xml, and add the following entry to the build -&gt; plugins section (<a class="offsite-link-inline" href="http://www.hagelnx.com/prog/814" target="_blank">THANK YOU, Hagel Blog</a>, for figuring out the problem with Spring's namespace files!):</p>

<pre class="brush: xml">
&lt;plugin&gt;
  &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
  &lt;artifactId&gt;maven-shade-plugin&lt;/artifactId&gt;
  &lt;version&gt;1.3.3&lt;/version&gt;
  &lt;executions&gt;
    &lt;execution&gt;
      &lt;phase&gt;package&lt;/phase&gt;
      &lt;goals&gt;
        &lt;goal&gt;shade&lt;/goal&gt;
      &lt;/goals&gt;
    &lt;/execution&gt;
  &lt;/executions&gt;
  &lt;configuration&gt;
      &lt;transformers&gt;      
      &lt;transformer implementation=&quot;org.apache.maven.plugins.shade.
             resource.AppendingTransformer&quot;&gt;
        &lt;resource&gt;META-INF/spring.handlers&lt;/resource&gt;
      &lt;/transformer&gt;
      &lt;transformer implementation=&quot;org.apache.maven.plugins.shade.
             resource.AppendingTransformer&quot;&gt;
        &lt;resource&gt;META-INF/spring.schemas&lt;/resource&gt;
      &lt;/transformer&gt;
    &lt;/transformers&gt;
  &lt;/configuration&gt;
&lt;/plugin&gt;
</pre>

<h3>Step 2: Run your maven build</h3>

<p>Now you can just issue a <code>mvn package</code> command, which will package up your content in the JAR file directly.</p>

<h3>Step 3: Execute your JAR</h3>
<p>Go ahead now and cd to target, and issue a command like:</p>
<pre>
java -classpath ./artifact-jar-file-name.jar package.path.and.mainclassname
</pre>
<p>And that's it. Pretty nifty feature, no?  Let me know if you've had success or problems with this approach.</p>]]></content></entry><entry><title>Spring UG Meeting recap - Oleg Zhurakousky on Spring Integration, Rabbit MQ, and GemFire</title><id>http://www.rimple.com/tech/2010/6/24/spring-ug-meeting-recap-oleg-zhurakousky-on-spring-integrati.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/6/24/spring-ug-meeting-recap-oleg-zhurakousky-on-spring-integrati.html"/><author><name>Ken Rimple</name></author><published>2010-06-24T16:06:06Z</published><updated>2010-06-24T16:06:06Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><span class="full-image-float-left ssNonEditable"><span><img src="http://www.rimple.com/storage/oleg-meeting-06-2010.jpg?__SQUARESPACE_CACHEVERSION=1277398666894" alt="" /></span><span class="thumbnail-caption" style="width: 400px;">Oleg Zhurakousky talking about S/I, Rabbit MQ, GemFire</span></span>Last night we had the privilege of hosting SpringSource's Oleg Zhurakousky&nbsp;at Chariot's training center for the Philly Spring User Group. &nbsp;Oleg talked about Spring Integration, and showed us how he recently put together a proof-of-concept of an integration platform using Spring Integration, the Rabbit MQ AMQP Server engine, and Gemfire, a distributed caching engine.</p>
<p>All of these tools are owned by VMWare/SpringSource. &nbsp;RabbitMQ and Gemfire are recent acquisitions.</p>
<p>Oleg started by giving us a basic overview of the challenges of JMS as a standard. &nbsp;Since it just defines an interface, interoperability is a big challenge. &nbsp;Also, since the producers and consumers both are wired to a destination via code / configuration, moving to another destination generally involves recompiling code on both sides. &nbsp;Also JMS developers generally have to deal with the fact that non-Java systems can't directly interface with JMS, various middleware, and connection management, to name a few issues.</p>
<h3>Enter AMQP</h3>
<p>The AMQP (advanced message queuing protocol) was created by a group of developers known as the <a href="http://www.amqp.org">AMQP working group</a>. &nbsp;It provides a wire-level message protocol that is built to support interoperability across all implementations. &nbsp;The key distinction between JMS and a wire-level protocol like AMQP is that AMQP does not specify an API, only the format of the data on the wire. &nbsp;The working group is comprised of companies from Microsoft to RedHat to financial companies like JP Morgan Chase, Credit Suisse, and Bank of America, where high-volume, real-time feeds of data need to be processed from a variety of systems.</p>
<h3>The RabbitMQ Acquisition</h3>
<p>SpringSource/VMWare acquired RabbitMQ this year with the goal of owning a highly scalable AMQP messaging service. &nbsp;Licensed using the Mozilla Public License (with of course, support contracts available) the platform runs on just about any platform, and the code is primarily written in ERLang. &nbsp;Oleg explained how easy it is to configure a cluster - once you start the cluster, elements are immediately replicated. &nbsp;You can set up things like in-memory or persistent replication stores, passive/active models, and a number of other configurations.</p>
<p>Oleg said the biggest thing that struck him about RabbitMQ is how fast it is. &nbsp;And he should know, working for a number of years in various message oriented middleware, and now becoming a member of the Spring Integration team with Mark Fisher. &nbsp;He showed us how quickly RabbitMQ starts, consumes and delivers messages, and how easy it is to administer using a simple command-line interface.</p>
<h3>Exchanges and Queues</h3>
<p>Unlike JMS, where developers attach connections and sessions, then produce messages and communicate with a wired Destination, RabbitMQ (and I assume AMQP) deals in terms of Exchanges and Queues. &nbsp;Exchanges receive messages from a sender, and Queues deliver messages to a receiver. &nbsp;Furthermore, these elements are just referred to by a name, not a physical class reference, so they can be reconfigured on the fly, at runtime.</p>
<p>In the demonstration, Oleg sent messages from a Spring client using Spring Integration, delivering them to an Exchange in Rabbit MQ. &nbsp;From there, he persisted the data in a persistent cache called Gemfire (more on that in a minute) and then another component delivered the message to the consumer via a queue.</p>
<p>Oleg says SpringSource is working on Spring components for RabbitMQ like a RabbitMQ Template and Proxy Factory Bean, to bring it into the Spring fold. &nbsp;From there, we can orchestrate the activity via Spring Integration, which can define workflow to move things along. &nbsp;</p>
<p>Oleg spent some time discussing Spring Integration's pipe-and-filters approach to integration, and also urged us all to pick up a copy of Enterprise Integration Patterns, which can be found online at <a href="http://www.eaipatterns.com">www.eaipatterns.com</a>&nbsp;(you can order the book via the website as well). &nbsp;He explained that Spring Integration is based very heavily on the EI patterns, so that the book will be a worthwhile investment if you are looking into using Spring Integration.</p>
<h3>About Gemfire</h3>
<p>Gemfire is a distributed cache engine that SpringSource also recently purchased. &nbsp;In the demonstration, as I said above, Oleg is persisting the data from the first (incoming) message flow into this cache so that it can be sent as quickly as possible. &nbsp;He says the team has been working with Gemfire's developers to take advantage of features like sequencing messages, which we assume will be forthcoming in a future release. &nbsp;</p>
<p>One of the interesting things about tools like Gemfire is the fact that large-scale sites like Amazon and eBay are actually already using huge, widely distributed caches to store data in memory across a large number of redundant hosts. &nbsp;This, in a way, makes the data safer than if it was just being backed up with a disaster recovery plan - if there are thousands of hosts replicating the information, and delivering it to consumers who need it in the regions they are requesting it from, it becomes difficult to stop hosting that data. &nbsp;A fascinating topic I'm really not doing justice to.</p>
<h3>Wrap-up</h3>
<p>Oleg's talk was really amazing. &nbsp;He showed how VMWare / SpringSource is acquiring companies that can deal with massive data delivery and storage problems. &nbsp;In my opinion VMWare is going after Oracle's business by side-stepping the physical box issue. &nbsp;Why use a series of physical servers with CPU licenses when you can just use time on a large scale cloud? &nbsp;Amazon does it. &nbsp;Google does it. &nbsp;With VMWare, Spring and some of these advanced technologies, it will be interesting to see some big customer rollouts in cloud-based systems, and to see how they stack up over offerings put together with conventional iron.</p>
<p>Note: &nbsp;<a class="offsite-link-inline" href="http://blog.springsource.com/2010/06/14/understanding-amqp-the-protocol-used-by-rabbitmq/" target="_blank">a recent blog post by Peter Ledbrook</a> describes Rabbit MQ a bit more in detail.</p>
<p><em>Ken Rimple works as the Education Director and delivers Spring training courses for Chariot Solutions, a SpringSource partner, and is host of the Chariot TechCast, which can be found at <a href="http://techcast.chariotsolutions.com">techcast.chariotsolutions.com</a>.&nbsp;</em></p>
<p>&nbsp;</p>]]></content></entry><entry><title>Rod Johnson Speech at Philly JUG - Recap : It's Roo and Grails FTW</title><category term="Opinion"/><category term="SpringSource Roo"/><category term="grails"/><category term="pontifications"/><id>http://www.rimple.com/tech/2010/6/1/rod-johnson-speech-at-philly-jug-recap-its-roo-and-grails-ft.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/6/1/rod-johnson-speech-at-philly-jug-recap-its-roo-and-grails-ft.html"/><author><name>Ken Rimple</name></author><published>2010-06-01T23:15:34Z</published><updated>2010-06-01T23:15:34Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><em>Disclaimer: &nbsp;I am a co-author of the upcoming Manning book, Spring Roo in Action, and a consultant for Chariot Solutions, a SpringSource partner. &nbsp;That said, I'm normally not a cheerleader. These are my thoughts around the recent speech by Rod Johnson of SpringSource. &nbsp;- Ken Rimple</em></p>
<div></div>
<p>Rod Johnson spoke last Thursday at the Philadelphia area Java User Group. &nbsp;Although I got called away for a family matter at the end (darn!) I heard what I hoped to be the case: that VMWare has a strong interest in improving developer productivity, in general, for cloud computing and for mobile applications, and to that end, invested in SpringSource, which is also leading SpringSource to invest heavily in both Grails and Spring Roo.</p>
<p>I am a fan of both platforms. &nbsp;Grails, with the Groovy language, is one of the best things to happen to dynamic programming on the Java VM in a long time. &nbsp;With access to any Java library or framework, including the built-in Spring and Hibernate platforms, it gives new meaning to "Rapid Application Development." &nbsp;</p>
<p>Spring Roo, on the other hand, solves the productivity problem more unconventionally. &nbsp;Pop quiz: &nbsp;when you hear the words "Aspect-J" and "Rapid Application Development" together, does it make sense? &nbsp;Most people view Aspect-J as powerful and complicated. &nbsp;While this is generally somewhat undeserved, Aspect-J, applied too liberally, can make a mess of an otherwise well-organized project. &nbsp;Most junior to mid-level developers fail to grasp it, and senior developers usually apply it surgically to do some really great things. &nbsp;Spring, in fact, uses aspect-oriented programming behind the scenes, when it does things like write dynamic Java Proxies to handle transaction management and security.</p>
<p>Roo is different because it uses a new feature of Aspect-J : Inter-Type Declarations. &nbsp;Using Aspect-J class files, developers can weave features from various aspect files into a single class at compile time. &nbsp;For example, Spring Roo Entities are comprised of at least four different class fragments - the entity class itself, with the fields of the entity, the JavaBean file, which contains setters/getters, the configurable, which adds the @Configurable annotation, and the Entity Aspect, which contains all of the methods to persist, find, query and remove entities from the database.</p>
<p>Rod's statement about how the Java platform has a short period of time to really take over the cloud computing industry was interesting. &nbsp;He stated that Java developers are "really smart, and that's a good thing," and then something along the lines of, "The problem is that Java developers think they are really smart, which is a bad thing." &nbsp;Probably paraphrased wrong, but rather hilarious. &nbsp;He put a hypothetical scenario in front of us stating that, given a moderate problem to solve, a Java, Ruby and .NET developer would go about it different ways:</p>
<p>First, the &nbsp;Ruby developer would get done on time. &nbsp;The .NET developer would also finish, but the Java developer would have reviewed ALL OF THE OPTIONS and not necessarily have coded a single thing. &nbsp;He says that is our problem, and that there are so many choices (a point I've argued a lot) that it makes it difficult for us to make decisions. &nbsp;I've seen a great talk by Scott Davis years ago that mentioned the "tyranny of choice" - when our combinations of choices go up, we begin to 'vapor lock' and paralyze ourselves with decisions. &nbsp;BTW because of Scott (and also Andy Hunt) there is a book on my reading list, "The Paradox of Choice."</p>
<p>So, we on Java have to get more rapid in our application development. &nbsp;And hopefully, that's where Spring Roo leads us. &nbsp;I developed on PowerBuilder back in the 90's for five years. &nbsp;Why? &nbsp;Because the alternatives for building business applications weren't so good: &nbsp;VB 2.0? &nbsp;terrible. &nbsp;FoxPro? &nbsp;What? &nbsp;C++? Come on! &nbsp;And then entered the web and Java, and we've been on the complexity train for a long time. &nbsp;Spring has done a ton to make this easier, but we have to do better. &nbsp; We must get to the point where it becomes trivial to boot up an application platform, to add persistence to our applications, to write a web application, to send emails, etc... &nbsp;Grails and Roo should get us closer to that goal.</p>
<p>I left at the point where Rod was laying out the mobile strategy. &nbsp;However, I see that Roo just got updated to 1.1.0.M1, which contains the starting point for building GWT applications (as well as Google App Engine back-ends). &nbsp;It certainly looks promising for the 1.1.0 GA release. &nbsp;But at least I think I've put decent bets on two good horses for rapid development on the Java platform with Grails and Roo.</p>
<p>Here's to what looks like an interesting 6-12 months on the Java platform.</p>
<p>&nbsp;</p>]]></content></entry><entry><title>If you ask me, I could write a book... Spring Roo in Action</title><id>http://www.rimple.com/tech/2010/5/13/if-you-ask-me-i-could-write-a-book-spring-roo-in-action.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/5/13/if-you-ask-me-i-could-write-a-book-spring-roo-in-action.html"/><author><name>Ken Rimple</name></author><published>2010-05-13T11:01:01Z</published><updated>2010-05-13T11:01:01Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>I am pleased to announce that, along with Craig Walls and my long-time friend and co-worker Gordon Dickens, I am writing a book in Spring Roo for Manning Publications.</p>

<p>I cooked up the idea after interviewing Ben Alex in November. Since Gordon and I are both Spring consultants and trainers and cover a lot of Spring-based technology, we felt that we were poised to jump on the book, as Roo is proving wildly popular and we already had the background to start quickly.  And anyway, I think Manning owes Gordon something as he owns and technically reviews just about every <span class="caps">MEAP </span>and a large number of books (just kidding).</p>

<p>We all thank Manning for giving us this opportunity. </p>

<p>Spring Roo in Action is going to cover all aspects of this tool, including basic functionality, <span class="caps">JPA </span>and <span class="caps">MVC </span>features, Roo and AspectJ <span class="caps">ITD</span>s, add-ons, and a lot more. I am currently wrapping up chapter one, and a <span class="caps">MEAP </span>will be coming within a few months. </p>

<p>This is a big commitment, and so I am going to start some occasional blogging on topics of interest around Roo, and monitoring the book forums and Spring forums, etc. I am looking forward to contributing, and Gordon and I are thrilled that Craig showed interest in participating as well.  He has already been extremely helpful to us in getting started.</p>

<p>More news soon.</p>
]]></content></entry><entry><title>My opening remarks</title><category term="ETE"/><category term="phillyete chariot chariot-news"/><id>http://www.rimple.com/tech/2010/4/9/my-opening-remarks-sigh.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/4/9/my-opening-remarks-sigh.html"/><author><name>Ken Rimple</name></author><published>2010-04-09T13:02:54Z</published><updated>2010-04-09T13:02:54Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><img class='iphone-image' src='http://www.rimple.com/resource/iphone-20100409090254-1.jpg?fileId=6472993'/></p><p>Due to a slight coordination snafu I didn't get to say my opening remarks.  Go, Cote!! </p><p>Here are my opening remarks for Friday April 9, ETE </p><p>Thanks to<br />  - ETE committees, speakers, people who helped with evening events, especially Rich Freedman who worked tirelessly before and during the event<br />- Have to give a shout out to my son - who made the tee shirt - he's 10!  Go Miles!!<br />- Recordings:  some good podcasts will go online soon. Goto http://techcast.chariotsolutions.com for more info<br />- Presentations will be available-  http://phillyemergingtech.com <br />- Flip your schedule over...<br />- Substitution Ezra Z. had a family matter, Yehuda will give a replacement talk @ "11:30" - "The Great Rails Refactor"<br />- ETE Hashtag:  #phillyete<br />- NING site : phillyemergingtech.ning.com<br />- be kind to wifi - cross fingers...<br />- Remind about surveys -<br />  - on the iPhone, Android app or phillyemergingtech.com,<br />       go to the bottom of the session information and click<br />       rate this session<br />- Intro to Michael Cote'<br />  - redmonk.com - Cloud Con East<br />  - podcasts, analysis</p>]]></content></entry><entry><title>Calling PostgreSQL Stored Procedures from Grails - Optimized Service class</title><category term="Chariot Solutions"/><category term="Groovy/Grails"/><category term="PostgreSQL"/><category term="chariot-news"/><id>http://www.rimple.com/tech/2010/3/26/calling-postgresql-stored-procedures-from-grails-optimized-s.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/3/26/calling-postgresql-stored-procedures-from-grails-optimized-s.html"/><author><name>Ken Rimple</name></author><published>2010-03-26T22:27:49Z</published><updated>2010-03-26T22:27:49Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>Here is a more-fully optimized Grails Service that creates and re-uses the thread-safe SqlFunction, StoredProcedure and JdbcTemplate classes.  Note - I'm using a <code>@PostConstruct</code> annotation on an <code>init()</code> method.  Yes, you can do that in Grails - it's just a Spring application.  This makes it possible to pick up the automatically injected <code>dataSource</code> and wire it into the various objects that require it.</p>

<p>Enjoy.</p>
<pre class="brush: groovy">
package org.playball.service

import org.springframework.jdbc.object.SqlFunction
import org.springframework.jdbc.core.JdbcTemplate
import org.playball.db.StoredProcSubclass
import javax.annotation.PostConstruct
import java.sql.Types


class StoredProcedureRunnerService {

  boolean transactional = true
    
  def dataSource
  def template
  def spcaller
  def sqlFunction


  @PostConstruct 
  def init() {
      int [] params = new int[1];
      params[0]=java.sql.Types.INTEGER;

      template = new JdbcTemplate(dataSource)
      spcaller = new StoredProcSubclass(dataSource)
      sqlFunction = new SqlFunction(dataSource,
                      "select salesByBookId(?)", params)
      sqlFunction.compile()

  }

  // automatically set up by name (Spring injected) on startup
  def sumBookSalesByBookIdWithJdbcTemplate(def bookId) {
      template.queryForInt("select salesByBookId(?)", bookId)
  }

  // use Spring JDBC's StoredProcedure class (see bottom of this class for definition)
  def sumBookSalesByBookIdWithSPSubclass(int bookId) {
      def map = spcaller.execute(bookId, bookId)
      map['#result-set-1']['result'][0]
  }

  def sumBookSalesByBookIdSqlFunction(int bookId) {

      def result
      try {
        result = sqlFunction.run(bookId)
      } catch (org.springframework.dao.TypeMismatchDataAccessException e) {
        log.error "Result type cannot be inferred - no result so returning 0"
        0
      }
      result
  }

  def sumBookSalesByBookIdGSQL(int bookId) {
      def gsql = new groovy.sql.Sql(dataSource)
      def results = gsql.rows("select salesByBookId(${bookId})")
      results["salesbybookid"][0]
  }
}
</pre>]]></content></entry><entry><title>Calling PostgreSQL Stored Procedures from Grails - Part 4 - Groovy SQL</title><category term="Chariot Solutions"/><category term="Groovy/Grails"/><category term="PostgreSQL"/><category term="chariot-news"/><id>http://www.rimple.com/tech/2010/3/26/calling-postgresql-stored-procedures-from-grails-part-4-groo.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/3/26/calling-postgresql-stored-procedures-from-grails-part-4-groo.html"/><author><name>Ken Rimple</name></author><published>2010-03-26T20:35:16Z</published><updated>2010-03-26T20:35:16Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>Every time I say "Groovy SQL" I feel there should be an implied comma.  Like, "Groovy, SQL!"</p>

<p>Groovy SQL is a simple API for calling SQL Statements in the vein of JdbcTemplate, but it's totally, um... Groovy.  Here is the very tiny snippet of code to call our Stored Procedure with Groovy SQL:</p>
<pre class="brush: groovy">
  def sumBookSalesByBookIdGSQL(int bookId) {
    def gsql = new groovy.sql.Sql(dataSource)
    def results = gsql.rows("select salesByBookId(${bookId})")
    results["salesbybookid"][0]
  }
</pre>
<p>There.  Isn't that, just, Groovy, SQL?  The results returned seem to be a map of results, with each one having a list of values.  I think for simple Stored Functions such as the one in Part 1, I say it's Groovy SQL FTW...</p>]]></content></entry><entry><title>Calling PostgreSQL Stored Procedures from Grails - Part 3, SqlFunction</title><category term="Chariot Solutions"/><category term="Groovy/Grails"/><category term="PostgreSQL"/><category term="chariot-news"/><id>http://www.rimple.com/tech/2010/3/26/calling-postgresql-stored-procedures-from-grails-part-3-sqlf.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/3/26/calling-postgresql-stored-procedures-from-grails-part-3-sqlf.html"/><author><name>Ken Rimple</name></author><published>2010-03-26T20:26:17Z</published><updated>2010-03-26T20:26:17Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><a href="http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/jdbc/object/SqlFunction.html"><code>SqlFunction</code></a>  is another class that takes a stored function (which is our sample procedure in Part 1), and runs it.  I've done a rather inefficient sample below.  In reality, you should be using the constructor passing the input types, and using the version of run which allows you to pass parameters.</p>

<h4>The SqlFunction section of our service</h4>

<pre class="brush: groovy">
def sqlFunction = new SqlFunction(dataSource, "select salesByBookId(${bookId})")
    sqlFunction.compile()
    def result
    try {
      result = sqlFunction.run()
    } catch (org.springframework.dao.DataAccessException e) {
      log.error "Result type cannot be inferred - " +
                 " no result so returning 0"
      0
    }
    result
</pre>

<p>I should explain a few things about the code snippet:</p>
<ul>
<li>The dataSource I auto-inject using <code>def dataSource</code> in the Grails Service</li>
<li>I return 0 if the key is wrong</li>
<li>The SqlFunction throws subclasses of <code>DataAccessException</code> when the call fails (if the row doesn't come back, for example.  You could use <code>TypeMismatchDataAccesException</code>, which is a subclass of <code>DataAccessException</code> but I chose the wider exception in the hierarchy.</li>
<li>I'm using the nifty Grails <code>log</code> variable, which is wired into every Grails object automatically.  You can control logging via the <code>Config.groovy</code> file in your <code>grails-app</code> directory.</li>
<li>Ideally, you should set up the SqlFunction instance and re-use it over and over again, as it is compiled.  Again, this is more showing you the features, not best practices, as I'm just blogging this to put a little more information out there.  I'll refactor this a bit later, if I get the chance...</li>
</ul>]]></content></entry><entry><title>Calling PostgreSQL Stored Procedures from Grails - Part 2 - Spring's StoredProcedure class</title><category term="Chariot Solutions"/><category term="Groovy/Grails"/><category term="PostgreSQL"/><category term="chariot-news"/><id>http://www.rimple.com/tech/2010/3/26/calling-postgresql-stored-procedures-from-grails-part-2-spri.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/3/26/calling-postgresql-stored-procedures-from-grails-part-2-spri.html"/><author><name>Ken Rimple</name></author><published>2010-03-26T19:56:11Z</published><updated>2010-03-26T19:56:11Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>In this part of my "Calling PostgreSQL procedures" series, I'm going to use the Spring StoredProcedure class to initiate the call.</p>
<h3>What is the StoredProcedure class?</h3>
<p>The Spring JDBC API has a class, <a href="http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/jdbc/object/StoredProcedure.html"><code>StoredProcedure</code></a>, that wraps calls to a stored procedure, providing access to both input and output parameters.  The general strategy for using this class is:</p>
<ol>
<li>Define your StoredProcedure subclass, listing parameters, and compiling the procedure (binding it to a Callable Statement)</li>
<li>Call the stored procedure using the <code>execute()</code> method, passing a <code>Map</code> of parameters</li>
</ol>

<p>My sample code follows:</p>
<h4>The Stored Procedure class</h4>

<pre class="brush: groovy">
package org.playball.db

import org.springframework.jdbc.core.SqlParameter
import javax.sql.DataSource
import org.springframework.jdbc.object.StoredProcedure

class StoredProcSubclass extends StoredProcedure {
    public StoredProcSubclass(DataSource ds) {
      super(ds, "salesByBookId")
      setFunction true
      declareParameter(
         new SqlParameter("book_id", 
                  java.sql.Types.INTEGER))
      compile()
    }

    public Map execute(Integer bookId) {
      Map inputs = new HashMap()
      inputs.put("book_id", bookId)
      return super.execute(inputs)
    }
}
</pre>

<p>I've placed this class in <code>src/groovy/org/playball/db</code>.  Now, to call it from our service from the last post, here is a snippet in the <code>StoredProcedureRunnerService</code> class:</p>

<pre class="brush: groovy">
  def sumBookSalesByBookIdWithSPSubclass(int bookId) {
    def spcaller = new StoredProcSubclass(dataSource)
    def map = spcaller.execute(bookId)
    // result is in entry '#result-set-1, 
    // with field 'result' which is a list, taking entry 0
    map['#result-set-1']['result'][0]
  }
</pre>

<p>Wasn't that fun?  The strangest thing is the result output.  Apparently, the return of the StoredProcedure call is a map of result sets, (#result-set-1), with each result being a map of fields w/values.  Figure that out in a unit test!  I actually hacked this with the Groovy Console, and it worked great for figuring that stuff out.</p>
<em>Please note - you should set up your StoredProcedure subclass in a Service or Spring Bean, not at the instance level, or you have to compile it each time.  Rather inefficient...  Will clean up later as this was just a demo of technology, not efficiency!</em>]]></content></entry><entry><title>Calling PostgreSQL Stored Procedures from Grails - Part 1, the setup and JdbcTemplate</title><id>http://www.rimple.com/tech/2010/3/25/calling-postgresql-stored-procedures-from-grails-part-1-the.html</id><link rel="alternate" type="text/html" href="http://www.rimple.com/tech/2010/3/25/calling-postgresql-stored-procedures-from-grails-part-1-the.html"/><author><name>Ken Rimple</name></author><published>2010-03-25T19:03:02Z</published><updated>2010-03-25T19:03:02Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>So, you have a want to write a Grails-based application, but your database has stored procedures? You can still use Grails for the MVC, and all of the rich plugins. This series of posts outlines a mechanism to get you there.</p>
<h3>The Setup</h3>
<p>Here's a table definition and a stored procedure to go with it. The table defines sales for a book in an online store (ala the old Sybase pubs database). The stored procedure (function) just goes and counts the total revenue from all sales on a given book id.</p>
<h4>The table schema</h4>

<pre class="brush: sql;">
CREATE TABLE sale
(
book_id BIGINT NOT NULL,
sale_id BIGINT NOT NULL,
quantity INT NOT NULL,
sale_price DECIMAL(6,2) NOT NULL
);
</pre>

<p>(other tables and keys omitted for brevity)</p>

<h4>Stored Procedure</h4>

<pre class="brush: sql;">
CREATE OR REPLACE FUNCTION salesByBookId(
 book_id int)
 RETURNS decimal
 AS $$
DECLARE
amount DECIMAL;
BEGIN
 select sum(s.quantity * s.sale_price) INTO amount
 from sale s, book b
 where s.book_id = b.book_id
  and b.book_id = book_id;

 RETURN amount;
END;
$$ LANGUAGE plpgsql;
</pre>

<p>Ok, so now we've got a procedure to call. You can invoke it in PostgreSQL like this:</p>

<pre class="brush: sql;">select salesByBook(80);</pre>

<p>So, what options do I have on the Grails side? Let's look at the simplest option, using Spring's JdbcTemplate:</p>
<h3>A Grails Service to call stored procedures</h3>
<p>Grails provides the service object for writing re-usable business logic (ala an EJB or Spring Bean). In fact, it actually IS a Spring Bean, and happens to be transactionally managed. Just use grails create-service to build one. Here is an example one using the Spring JdbcTemplate (see the fully optimized version <a href="http://www.rimple.com/tech/2010/3/26/calling-postgresql-stored-procedures-from-grails-optimized-s.html">in this post</a>):</p>

<pre class="brush: groovy;">
class StoredProcedureRunnerService {
 def dataSource
 boolean transactional = true

 // automatically set up by name (Spring injected) on startup
 def sumBookSalesByBookIdWithJdbcTemplate(def bookId) {
     def template = new JdbcTemplate(dataSource)
        template.queryForInt("select salesByBookId(${bookId})")
     }
  }
</pre>
<p>Some items of note:</p>
<ul>
<li>Grails is a Spring application development platform. So you can easily import any standard Spring APIs such as JdbcTemplate</li>
<li>note the <code>def dataSource</code> in the code above. Spring will look for a bean it has created with that name and inject it automatically. Our Grails datasource has the Spring Bean name of 'dataSource'</li>
<li>The last line of <code>thesumBookSalesByBookIdWithJdbcTemplate</code> method just calls <code>template.queryForInt</code> - that happens to be the last evaluated statement in the method, which Groovy uses as the return value of the method. In other words, the value returned is the value of the queryForInt method.</li>
</ul>
<p>So, there you have it. To use this service, just do a defStoredProcedureRunnerService at the top of a Controller, and call it - that class is a Spring Bean, and is autowired at startup time directly into the Controller. Here is my test controller (a fragment):</p>
<p>
<pre class="brush: groovy;">
class TestController {
  def storedProcedureRunnerService
  def index = {
   render(view: "index", 
     model: [bookId: params.bookId != null ? 
          params.bookId : 0])
 }

  def template = {
     def safeBookId = parseInt(params.bookId)

     def result = storedProcedureRunnerService.
       sumBookSalesByBookIdWithJdbcTemplate(safeBookId);

     def model = [result: result,
                  bookId: safeBookId]
        render(view: "index", model: model)
  }
}
</pre>]]></content></entry></feed>