Wednesday, December 10, 2008
Gateway Groovy Users Recap
Monday, December 8, 2008
GSP Page Without a Controller
With any of these approaches you have most of the power of GSP. You can use the standard Grails GSP tags as well as any custom tags added to your project, you can include Groovy code in your pages (but please keep it to a minimum) and you have access to the objects that Grails makes available to all GSP pages, such as request, session and params. What you don't have is a way to pass model data to your page or to perform other operations before your page is rendered.
Groovy User Groups
Sunday, November 23, 2008
Final Day of Final No Fluff Just Stuff of 2008
Saturday, November 22, 2008
NFJS Chicago Day Two was packed!
Friday, November 21, 2008
NFJS Chicago Day One Wrapup
Chicago NFJS Day One
Tuesday, November 11, 2008
Congratulations to SpringSource!
Uber-GenerateAll
Friday, October 31, 2008
Don't you hate blog posts about blogging?
Then, I figured, well, I just started a new job and I don't have time to blog. That sounded like a reasonable reason, except that I'm currently working from home and avoiding 2 1/2 hours on the road each day. So I actually have more time than I've had for a while.
Then, the interesting thought hit me that I don't have anything interesting to blog about. That one didn't last long. With all that is going on in the 2G community and with the cool stuff I'm working on at Contegix, that was a poor excuse for an excuse. So, I'm still stuck inexcusably underblogged.
I'll keep on looking for that perfect excuse, but in the meantime I'll try to start blogging more. At least this one should get Ben off my back for a while. :)
Tuesday, October 7, 2008
Catching Up
Thursday, September 11, 2008
Introducing Joshua Arthur Klein
Tuesday, August 26, 2008
BGG takes top honors at CapJug Meeting!
When we have this many books to give out we like to treat it like a poll. So, I'll describe each of the books and then start drawing names. Each winner can take their pick from the books remaining. I am happy to announce that Beginning Groovy and Grails was the first pick! Congratulations to Christopher, Joseph and James! The CapJug pick of the months is quite an honor. We still have another copy to give away next month so we'll see if they can hold the record for a second month.
It is great to see the growing interest and excitement in Groovy and Grails at our Java User Group and I know that ours is not unique. Java User Groups all over the world are beginning to embrace the next generation of Java!
Thursday, August 14, 2008
Out of the Box
Anyone involved in software development has heard, read and probably used this term at one time or another. If you are involved in Groovy and Grails development you probably hear it all the time. I think Scott Davis holds the record for most uses of the term in a single presentation. In the book "Beginning Groovy and Grails: From Novice to Professional" (an excellent book, by the way, which I am almost done poring over and will write a review on soon), this term appears about a dozen times. It's easy to understand why since Grails does come with so many features and so many things that just work right out of... well you know what I mean.
So, you ask, what's the big deal? It's just plain wrong, that's what. It's difficult these days to find software or software development tools that were ever in a box to begin with. This is especially true with open source tools like Groovy and Grails. And I am worried that using this kind of inaccurate term is going to affect the way others look at our profession. I mean, as programmers we're supposed to be at least somewhat intelligent, but what are people going to think when they hear us talking about features and benefits coming out of a box that never existed?
I think this is a serious problem and not an easy one to solve. How else can we express the magic of things like GORM without using so many words that we get jaw cramps. Nonetheless, it's a problem that must be solved. If we do not want people to start lumping us in with the likes of used car salesmen or, even worse, lawyers, we had better get started looking for another, more accurate, term.
I think we can do it if we all work together and if we're willing to think outside the box.
Saturday, August 2, 2008
No Fluff in Green Bay
But what it lacks in quantity it more than makes up for in quality! The speaker lineup, though limited, is top notch. Yesterday (Fri) Jeff Brown was extolling the goodness that is Groovy and Grails, Venkat Subramaniam was covering Agile development, mocking for unit testing, and testing our Java kung fu, and capping off the lineup was Mark Richards who gave a two-fer on Enterprise messaging with JMS followed by an SOA class.
Then after we'd all finished up our steak dinners Venkat treated us to a brand new keynote that was eye-opening, inspiring and hilarious all at the same time.
So far, so good. Now to head downstairs for day two. Today Jared Richardson, Brian Sletten and, local boy, John Carnell will be joining us. It'll be great as long as my head doesn't explode.
Tuesday, July 15, 2008
Grails and EJB 3 Session Beans
The problem came about because we were working with EJB3 this time. I had heard that it should work the same but it doesn't. I eventually found that it is still extremely easy to do (this is Grails we're talking about after all) it's just different.
For starters the Spring class that we used to connect to an EJB2 session bean, SimpleRemoteStatelessSessionProxyFactoryBean (I wonder if there is a TinyURL! for class names) was not working with EJB3. Several people on the forums said that it should, but our application did not believe them. It turns out that there is a Spring class that does work with EJB3 and it even has a shorter name! The JndiObjectFactoryBean is a general purpose Factory for looking up JNDI objects and making them available to other beans. The JndiObjectFactoryBean will even use the JndiTemplate that I had setup before, though I'll show it again so you don't have to hunt it down.
So now we should be in business. Except that it didn't work. When using the SimpleRemoteStatelessSessionProxyFactoryBean we could just use the Session Bean's simple interface name, which was also its JNDI name. That was not working with the JndiObjectFactoryBean. This critter wanted a fully qualified, certified and USDA approved JNDI name. The bummer here is that this is vendor specific. So the rest of this will work for BEAORACLE WebLogic but it might be completely different for your app server.
First we have to make sure that the EJB3 session bean has the mappedName attribute in the @Stateless annotation. (In our case ...mappedName="CoverageSession") That makes up the first part of the JNDI name. Then we add a # symbol and top it off with the fully qualified name of the Remote Interface. So we ended up with something like this for our JNDI name: CoverageSession#org.blah.app.ejb.session.ICoverageSessionRemote Once we gave it that mouthful it was happy.
Here I'll show a slightly modified version of our resources.groovy file:
beans = {
ejbJndi(org.springframework.jndi.JndiTemplate){
environment = [
"java.naming.factory.initial" : "weblogic.jndi.WLInitialContextFactory",
"java.naming.provider.url" : "t3://some.enterprise.server:7001"
"java.naming.security.principal" : "dave",
"java.naming.security.credentials" : "1234" ]}
coverageSession(org.springframework.jndi.JndiObjectFactoryBean){
jndiName = "CoverageSession#org.blah.app.ejb.session.ICoverageSessionRemote"
jndiTemplate = ref("ejbJndi")
}
}
Now we can inject the session bean into a Grails Service and we can call its methods to retrieve and save EJB3 entities from that portion of the application that was written before we began using Grails and it all just works and I'm happy!
I'm still hoping to be able to convert the entire application to Grails before we go production but in case we can't the ability to integrate Grails with all of our existing Java technologies is a big help.
Wednesday, June 11, 2008
Grails to the Rescue
I've read and heard about death march software projects before but I had never experienced one until recently. About a month ago I was put in charge of a 2 1/2 year JSF/EJB project that had 8 months left and was less than half done. (By the way, that's my excuse for not blogging in a while. It's not as good as Glen Smith's excuse but it's all I've got) At first this was quite disheartening. I assessed the situation and made it clear that there was no way that we could meet the deadline but was told to just "do the best we could". So, I marched on...
Then, as I dug into the project more, I discovered that there were major pieces of the application that were isolated enough that they could be done in a different environment without impacting the overall system. Grails to the rescue. We are now using Grails for most of the remaining development and gaining momentum quickly. Two of the four of us on this team have Grails experience but the other two are coming up to speed very quickly and, I might add, enjoying their jobs more than they have for some time. One of the pleasant side effects of using Groovy and Grails is increased job satisfaction and motivation.
While there's still much to do and it is still unlikely that we will make that deadline, switching from JSF/EJB to Grails has turned this death march into a forlorn hope. In this case the reward won't be fame, glory and promotion but it just might be another IT shop standardizing on Groovy and Grails. Here's hoping!
Saturday, May 17, 2008
Introducing JugList.net
JugList.Net is a searchable directory of Java User Groups around the world.
You can search for a JUG (Java User Group) by name, city, state/province or country. If you still can't find a JUG in your area, there is a link to an article, by yours truly, that gives some tips on starting your own group.
Java User Groups are a valuable resource for honing your craft and building your career. They also provide a great way for experienced programmers to give a little back to the community. If you are not involved in a JUG yet, then check out juglist.net and find one near you.
Friday, May 16, 2008
Another way to use Groovy in the Enterprise
In this example we'll build a utility class that will use convention to turn an SQL select statement into a List of data transfer objects.
Our goal here is to take an SQL statement and a Class, execute that statement and use the results to populate instances of the Class. We will assume the convention of camel case for object properties and underscores for database fields, so that a field called LAST_NAME would be mapped to a property called lastName. We will also assume that the select statement will only return fields that have a corresponding property in the Class.
So let's see what this might look like:
static Collection getData(String query, Class clazz, Connection con){
def field = ''
def result = []
def sql = new Sql(con)
sql.rows(query).each {row ->
def dto = clazz.newInstance()
row.keySet().each{
field = toCamelCase(it)
dto."${field}" = row."${it}"
}
result << dto
}
result
}
After defining a few variables, we create our groovy.sql.Sql object using the constructor that takes a Connection. This will allow us to use Connections provided by an application server such as WebLogic or WebSphere. We could easily change this method to take advantage of the other constructors.
Next we'll call the rows method of the Sql class, which will execute the SQL statement and return an ArrayList of GroovyRowResults. Now we'll iterate through this ArrayList and create a new instance of our DTO class for each row. GroovyRowResult implements the Map interface so we can loop through its keys with row.keySet().each. This will give us each of the fields in that row and we will turn them into property names with a call to the toCamelCase() method (which we'll look at shortly). Notice how we take advantage of GStrings to dynamically access properties of our DTO as well as keys of the row map. After we assign each of the fields in the row to properties of the DTO instance we add it to the result List. When the loop is done we just return the List. Obviously, more can be done to make this more robust and more flexible, but it's pretty amazing how easy it was to build a Groovy class that can replace tons of repetitive Java code.
Let's take a look at how we could use this class from a Java project:
...
Connection con = getConnectionFromPool();
String query = "SELECT FIRST_NAME, LAST_NAME, EMAIL FROM MEMBER";
Collection members = GroovyData.getData(query, MemberDTO.class, con);
...
That's all there is to it.
Now let's take a quick look at the toCamelCase() method we mentioned above. This doesn't directly have anything to do with the purpose of this post, but I am hoping that someone might see this and offer a groovier way to do the same thing. Basically the goal is to take a database field name such as LAST_NAME and turn it into a camelCase string like lastName. Here's how I did it:
static String toCamelCase(String val){
def sb = new StringBuffer()
Boolean newWord = false
val.toLowerCase().each{
if (it == '_')
newWord = true
else{
if (newWord){
newWord = false
sb << it.toUpperCase()
}
else
sb << it
}
}
sb.toString()
}
I was sure there was a groovier way to do this and, sure enough, Andres Almiray came up with this awesome improvement:
static String toCamelCase(String val){
def result = val.split("_").collect { word ->
word[0].toUpperCase() + word[1..-1].toLowerCase()
}.join("")
result[0].toLowerCase() + result[1..-1]
}
Thanks Andres! And if that wasn't groovy enough, Ted Naleid came up with this cool mix of regular expressions and meta-programming. Good stuff Ted!
def camelCaseConverter(orig) {
orig.toLowerCase().replaceAll(/_(\w)?/) { wholeMatch, firstLetter ->
firstLetter?.toUpperCase() ?: ""
}
}
String.metaClass.toCamelCase = {->
camelCaseConverter(delegate)
}
Thursday, May 1, 2008
Groovy and Grails at JavaOne
Then for the rest of the week a groovy search in the Content Catalog turned up the following list:
ID | Session Title | Speaker(s) | Date / Time | Room | |
TS-5771 | The Duke and the Elephant: PHP Meets Java™ Technology--the Best of Both Worlds | Rob Nicholson, IBM |
| Esplanade 301 | |
TS-5764 | Grails in Depth | Guillaume Laforge, G2One, Inc., Graeme Rocher, G2One Inc |
| Esplanade 307-310 | |
BOF-5613 | Jersey: RESTful Web Services Made Easy | Jakub Podlesak, Sun Microsystems |
| Esplanade 307-310 | |
PAN-5435 | The Script Bowl: A Rapid-Fire Comparison of Scripting Languages | Guillaume Laforge, G2One, Inc., Charles Nutter, Sun Microsystems, Inc., Jorge Ortiz, Stanford, Raghavan Srinivas, Sun Microsystems, Inc., |
| Gateway 104 | |
TS-5572 | Groovy, the Red Pill: Metaprogramming--How to Blow the Mind of Developers on the Java™ Platform | Scott Davis, Davisworld Consulting, Inc. |
| North Mtg-121/122/124/125 | |
TS-5815 | Going Mobile with JavaFX™ Script Technology, Groovy, and Google Android | Mike Mannion, Canoo Engineering AG |
| Esplanade 301 | |
TS-6050 | Comparing JRuby and Groovy | Neal Ford, ThoughtWorks Inc. |
| North Mtg-121/122/124/125 | |
TS-5274 | Groovy on a Cloud: Testing Java™ Platform, Enterprise Edition (Java EE Platform) Applications on Amazon EC2 | Chris Richardson, Chris Richardson Consulting, Inc. |
| Gateway 104 | |
TS-6213 | Boldly Go Where the Java™ Programming Language Has Never Gone Before | Geert Bevin, Terracotta |
| North Mtg-121/122/124/125 | |
BOF-5102 | Cooking Your Own Groovy Builder: A Step Forward into Domain-Specific Languages | Andres Almiray, Oracle, Ixchel Ruiz, Clemente Camara y Asociados |
| Gateway 104 | |
BOF-5110 | Extending Groovy’s Swing User Interface in Builder to Build Richer Applications | Danno Ferrin, Intelligent Software Solutions, Inc., James Williams, Spatial Networks |
| Hall E 133 | |
TS-5793 | Groovy and Grails: Changing the Landscape of Java™ Platform, Enterprise Edition (Java EE Platform) Patterns | Guillaume Laforge, G2One, Inc., Graeme Rocher, G2One Inc |
| North Mtg-121/122/124/125 | |
TS-5693 | Writing Your Own JSR-Compliant, Domain-Specific Scripting Language | John Colosi, VeriSign, Inc.; David Smith, VeriSign Inc. |
| Esplanade 301 | |
TS-6457 | Choosing Your Java™ Technology-Based Web Framework: A Comparison | Richard Pack, Hyperic; Stacey Schneider, Hyperic |
| Esplanade 307-310 | |
TS-6606 | Patterns for Integrating Java™ and JavaScript™ Technology: Tales from the Front Lines | David Caldwell, David P. Caldwell, Inc. |
| North Mtg-121/122/124/125 | |
BOF-5101 | Boosting Your Testing Productivity with Groovy | Andres Almiray, Oracle;, James Williams, Spatial Networks |
| Gateway 102/103 | |
TS-5098 | Building Rich Applications with Groovy's SwingBuilder | Andres Almiray, Oracle;, Danno Ferrin, Intelligent Software Solutions, Inc. |
| Esplanade 305 | |
TS-6050 | Comparing JRuby and Groovy | Neal Ford, ThoughtWorks Inc. |
| Esplanade 303 | |
TS-6039 | Jython - Implementing Dynamic Language Features for the Java™ Platform Ecosystem | Jim Baker, Zyasoft, Tobias Ivarsson, Neo Technology |
| Esplanade 305 |
Well, if you read this far and if you happen to be wandering around the Pavillion on Tuesday afternoon at 3:30, I will be giving a mini-talk on Java User Groups at the java.net Community Corner. (That way I can say that I gave a presentation at JavaOne).
Monday, April 14, 2008
NoFluffJustStuff JUG Events
As the leader of a JUG (Capital Java User Group - Madison, WI) I appreciate all the support that the folks at NoFluffJustStuff provide to the Java community. As a Groovy / Grails developer, I also appreciate the way that they are helping to usher in the next generation of Java!
Thursday, April 10, 2008
Google App Engine - Vote for Groovy
You can add your support by going to their issue list (http://code.google.com/p/googleappengine/issues/list) and giving that issue a star. You can also add a comment but it's the number of stars that moves an issue to the top of the list. Even though the Java/Groovy request is the first one entered (id = 1) it is currently ranking 5th in stars. Slightly behind Ruby and a good deal behind Perl. This is a great opportunity to be a squeaky wheel. So head on over to the list and give Groovy a star!
Tuesday, April 8, 2008
Programming Groovy has shipped!
I'll try to post a review soon, but I'll give you the short version now:
It's a great book and if you have any interest in Groovy you should buy it right away!
Thursday, April 3, 2008
Groovy and Grails at ApacheCon
You can find more info and a list of proposed sessions in this Nabble thread:
http://www.nabble.com/Groovy-at-ApacheCon-US-2008-to16450918.html
Wednesday, April 2, 2008
Searchable Plugin: Just use it!
I've been working with Grails for over a year, all the while hearing great things about the Searchable plugin. So far, I have only had the need for simple searches so I just never bothered to look at Searchable. That was really dumb! Like, "why bother learning how to use a hammer, this rock is working fine".
So, just the other day, I had a search that was going from two potential fields to three or four. So, I decided to take a look at the Searchable plugin and see how "hard" it would be to get it integrated. Well, as with most things in the Groovy / Grails world, I had it up an running almost before I had finished reading the wiki page. It is so easy and so powerful that I can't see myself building any kind of search without it.
Here's a simple scenario for an example: We have a Company class that has half a dozen fields that users might want to search on and they want the search form to be at the top of the list page.
First we install the plugin like so:
> grails install-plugin searchable
Then add the following line to Company.groovy:
static searchable = true
Next we'll add a search action to our controller:
def search = {
def companyList
if (params.query)
companyList = Company.search(params.query).results
else
companyList = Company.list()
render(view:'list', model:[companyList : companyList])
}
Finally we add a search bar to our list.gsp:
< div class="nav">
< g:form action="search" method="post">
Search: < input type="text" name="query">
< input value="Search" type="submit">
< /g:form>
< /div>
Now our users can search for companies by any of the properties using one or more search words and the result will show up in our standard list page. Searchable also supports complex queries which you can read all about at grails.org/Searchable+Plugin+-+Searching#SearchablePlugin-Searching-StringQueries
There's more that we could do here such as pagination, but I'll leave that as an exercise for the reader. How hard could it be?
Friday, March 28, 2008
Did you mean "rails"?
Ok, so there are 417 Rails jobs on dice and only 12 Grails jobs, but that's no excuse. I'm going to keep an eye on this and I'll report back when it changes.
Wednesday, March 26, 2008
Integrating Grails with EJB 2 applications
In this example we have an EJB 2 server running in WebLogic. There is a CMP entity bean called Employee, a stateless session bean called EmpSession and a data transfer object called vEmployee. The EJB components and the DTO are in a jar called EmpEjb.jar. The session bean contains methods for retrieving and saving Employee entities via the vEmployee DTOs. We will focus on on how to get access to the EmpSession instance from our Grails application.
First we'll add a couple of beans to our grails-app/conf/spring/resources.groovy file using the SpringBuilder DSL.
beans = {
ejbJndi(org.springframework.jndi.JndiTemplate){
environment = [
"java.naming.factory.initial" : "weblogic.jndi.WLInitialContextFactory",
"java.naming.provider.url" : "t3://some.enterprise.server:7001",
"java.naming.security.principal" : "dave",
"java.naming.security.credentials" : "1234"
]
}
empSession(org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean){
jndiName = "EmpSession"
businessInterface = "com.enterprise.some.ejb.session.EmpSession"
jndiTemplate = ref("ejbJndi")
}
}
Let's look at what this code is doing. We have what looks like a method: ejbJndi. It is really a Spring bean id and its argument is the bean class. The block that follows includes one or more property assignments in the form of properyName = propertyValue. for the ejbJndi bean we only have one property, environment, which in turn contains several
Next we declare our remote session bean using Spring's SimpleRemoteStatelessSessionProxyFactoryBean (they said "Simple" not "Short"). We declare this the same way as the ejbJndi bean. This one has three properties, the session bean's jndi name, its remote interface class and a reference to the JNDI Template. For this last property we use the form property = ref("referencedBeanId").
Now we need to copy some jars to our application/lib directory. Since we are using WebLogic all of the EJB and JNDI classes we will need are in weblogic.jar. You may have one or more jars depending on your application server. Our EJB components and our DTO classes are in a single jar, EmpEjb.jar. These may often be in different jars, in which case both would need to be placed in the lib directory.
Beans defined in resources.groovy can be auto-wired by name so we can just place def empSession in any Service or Controller class and start calling session methods.
With this ability to integrate so easily with legacy applications there is just one less reason not to start using Grails in the enterprise.
Thursday, March 20, 2008
Sven and Glen are at it again!
There's more but you'll just have to tune in for yourself. I have to say that I really appreciate the conversational style they have now with Sven and Glen; now if they could only find a Ben ...
Wednesday, March 19, 2008
You learn something new every day... on the Grails Mailing List
For example, just the other day, I came across this very helpful post by Chris Chen that describes a simple way to deal with get methods in your domain class that don't have a corresponding set method (ie. calculated properties). If you try to do this without some extra code, you will get a PropertyNotFoundException. In the past I've usually handled this by renaming the method so it doesn't start with get, even though get might make the most sense. The alternative is to use a transients list, but that just doesn't seem right to me for this situation.
What Chris suggested was to dynamically type your get method. So, for example, if you have a Parent class which has a collection of Child and you want to find the oldestChild, you can do this:
class Parent {
...
static hasMany = [children: Child]
def getOldestChild(){
//logic here to get oldest child
}
}
That's all there is to it. Just use def instead of a static type. Now, as far as Grails is concerned you will have a property called oldestChild. It will even show up in the scaffolding. Hibernate, however will remain blissfully ignorant. Now that I've seen this it seems painfully obvious, but if I hadn't read Chris' answer in that post, I would have never thought of it on my own.
This is just one example, there are many others, so if you aren't signed up for the mailing list or at least perusing the archives, I would encourage you to get started today.
Monday, March 17, 2008
Use .each, Save A Puppy.
My favorite line from the last episode was when they were discussing the old Java for loop and Glen was talking about how he couldn’t imagine using a for loop to iterate over a collection and then said that “Every time you do that a puppy dies somewhere”. So next time you find yourself falling back into old habits, think of the puppies and use .each
Be sure to check out the podcast. It’s supposed to be out fortnightly (that’s every two weeks for us Yanks) so the next one should be here soon!
Sunday, March 16, 2008
I Survived SD West
There was some great technical content and some very interesting people at this conference, but what made the week memorable for me and the family was that I was scheduled to speak at it. My session was during the last slot of the last day (they always save the best for last, right?). Still mulling over the ideas and inspiration gained from the Groovy/Grails Experience last month, I spent most of my spare time in my room working on my slides, which my kids proofed for me from home. (slides and code sample can be downloaded here)
This is the first of the Dr. Dobbs family of conferences to have any Groovy or Grails presentations: it had one of each. First on Monday Andy Glover gave a very interesting and entertaining half day tutorial on Groovy. You could feel the excitement in the room. In fact a guy sitting next to me leaned over at one point and said "This stuff is amazing!"
Later came my session on Agile Web Development with Grails .... I thought I had my nerves under control, and the audience was involved and had many good questions. It was obvious that these folks were thinking about how and if they could start using Grails. After it was over, it was great to have several people stay and offer nice comments, or ask additional questions. However, one kind lady made the comment that it was "very brave of you to get up there in front of all these people". Perhaps my nerves weren't quite as controlled as I thought.
While the Groovy and Grails aspects were a high point for me, there was some other good stuff at SD West. The Beautiful Code panel was a lot of fun and contained some good insights. The Developer Bowl was a hoot and a half and, James McLurkin of MIT gave a very interesting presentation on robotics and how to save the world by being a geek. Then there was Uncle Bob. Robert Martin has always been one of my favorite speakers and although I only caught one of his talks this time, Clean Code was terrific. We all know shorter methods are better but Uncle Bob gave some very practical suggestions and examples of how to do it.
It was all good, but I'm glad to be home.
PS: The kids didn't really have to carry me on a stretcher, but its good to know that if I ever need this type of assistance, they are up for it.
Saturday, March 15, 2008
Grails' ORM DSL Rules!
save()
, delete()
, list()
, get()
, findByProp1AndProp2
, and the list goes on. I still appreciate these features, but a more recent addition to GORM has moved to the head of the class with me. The ORM DSL introduced in Grails 1.0 makes it trivially easy to map your domain classes onto legacy database schemas. It was already possible to do this in Grails and Jason Rudolph has given us some helpful tutorials, but the ORM DSL makes it so easy even I could do it. And that's important because it enabled me to get Grails into a production project with my current client. They were impressed with the productivity promise of Grails and were quite ready to look into something beyond the JSF/EJB stack they had been fighting with, but having anything or anyone besides the DBA creating the database schemas was out of the question.Let's take a look at just how easy it is to use the Grails ORM DSL. For our example we will work with the tried and true
Book
and Publisher
classes, but with legacy tables in an Oracle 10g database.Here's our domain classes in Grails:
class Publisher {
String name
String city
static hasMany = [books : Book]
}
class Book {
String title
String author
Integer pages
Publisher publisher
static belongsTo = Publisher
}
And here's the legacy tables we have to work with:
TABLE PUB01
Column Name Data Type
ID_PUB_PK NUMBER
PUB_NM VARCHAR(100)
PUB_CTY VARCHAR(100)
SEQUENCE ID_PUB_PK_SEQ
TABLE BK01
Column Name Date Type
ID_BK_PK NUMBER
BK_TITLE VARCHAR2(100)
BK_AUTHOR VARCHAR2(100)
BK_PGS NUMBER
ID_PUB_FK NUMBER
SEQUENCE ID_BK_PK_SEQ
Now let's map our
Publisher
class to the PUB01
table:
class Publisher {
String name
String city
static hasMany = [books : Book]
static mapping = {
table 'PUB01'
columns{
id column: 'ID_PUB_PK'
name column: 'PUB_NM'
city column: 'PUB_CTY'
}
id generator:'sequence', params:[sequence:'ID_PUB_PK_SEQ']
}
}
Let's look at what we did here. We created a static block called '
mapping
'. Inside the mapping
block, we first define the table for this class (note that the table name and all column names are in quotes), and then we create a nested block called columns
. In the columns
block we list each property, a space, and then column: 'column name'
. Using the word 'column' on each line might seem redundant, but there are other attributes of a property that can be set in the columns
block, so when you are setting the column you have to be specific. After the columns
block we have the id
generation scheme, which we'll discuss in a bit.Now we'll modify our
Book
class and discuss one interesting thing there:
class Book {
String title
String author
Integer pages
Publisher publisher
static belongsTo = Publisher
static mapping = {
table 'BK01'
columns{
id column: 'ID_BK_PK'
title column: 'BK_TITLE'
author column: 'BK_AUTHOR'
pages column: 'BK_PGS'
publisher column: 'ID_PUB_FK'
}
id generator: 'sequence', params:[sequence:'ID_BK_PK_SEQ']
}
}
You'll notice that this was pretty much the same thing we did with
Publisher
. The one difference is the way that we mapped the relationship. The publisher
property, which is of type Publisher
, is mapped using the foreign key for the Publisher
table, 'ID_PUB_FK'Now let's talk about id generators. In Grails you can use any id generation scheme supported by Hibernate. To do this with the ORM DSL, you basically call an
id
method and pass it a Map
. The first key in the Map
is the word generator
, and the first value is the name of the generator class, such as 'hilo
', 'seqhilo
', 'identity
' or 'sequence
'. The Hibernate docs list the possible classes and their params. The next key is the word params
and the value is another Map
. The keys for this Map
are name attributes of each of the param tags taken by this generator class. The values are the bodies of the param tags. In the case of the sequence generator we only have one param tag, with a name attribute of sequence
, and the body would be the name of the sequence in the database, in our example 'ID_PUB_PK_SEQ
' or 'ID_BK_PK_SEQ
'. One more note: We were able to talk our DBA into adding a number field called
version
to each of our legacy tables, so we left versioning on. If you cannot add a version
field to your tables (and don't already have one), then you can turn off versioning by adding the line version false
after the line where you declare your table. If you do this you will lose the optimistic concurrency that Grails / Hibernate give you and will have to provide some other method of handling concurrency.There is a great deal more that you can do with the Grails ORM DSL, but I only wanted to discuss features that I've actually worked with. As I dig into this more I may add more details, but in the meantime you can read all about it in the Grails online docs.
Monday, March 3, 2008
Good Stuff In Milwaukee
The Red Pill talk dug into some the really cool stuff you can do with Groovy once you're ready to take it to the next level. He covered things like method pointers, closures, named arg/var arg constructors and operator overloading. Then he got into meta-programming and,well I don't want to give too much away. You'll just have to catch an NFJS event near you and see for yourself.
Next up was Scott Davis again with “Grails for (recovering) Struts Developers”. This was basically an introductory Grails talk (and a good one), but targeted at developers who were used to the Struts way of doing things.
The next day I can't report on because I went, with my family to the Milwaukee zoo. Well I guess I could report on it but it probably wouldn't be very interesting for someone reading a Groovy/Grails blog. Except that they did have some very groovy apes there.
Sunday morning Venkat Subramaniam gave a presentation on TDD/BDD that was very motivating. He showcased FIT, FitNesse and easyb, by the oh so hip, Andy Glover.
Then on to more testing stuff, Jeff Brown gave a talk on TDD in Groovy and Grails. Testing is another great showcase for the power of Groovy and Jeff did an excellent job of highlighting that.
Then came a hearty lunch, visits with a bunch of fellow Madisonians and the speaker panel. The speaker panel is always a high point of a NFJS event and this one was no exception. Brian Sletten continues to improve his ability to turn almost any question into a discussion of the Semantic Web. (go Brian!). There were two more sessions in the afternoon but I had to catch a flight out to California for SD West, where I will be presenting on “Agile Web Development with Grails” this Friday. Speaking of which, I better get back to work on my slides. But firs I want to mention how great it was to see so many members of the Capital Java User Group at the Milwaukee conference. We could have held a meeting there and it might have been one of our best turnouts. Also I have to give a big Thank You to the good folks at Smart Solutions who offered to send all of their Java developers to this conference. Now that's a forward thinking consulting firm. As well as a great company to work for.
Wednesday, February 27, 2008
Groovy/Grails Experience... The name says it all
Now that I’m caught up on my sleep, I will give a few impressions. But first let me say that several more prolific writers than myself have already written about the event. You can see a bunch of them at the GroovyZone: http://groovy.dzone.com/news/2gx-impressions
This was the best conference that I have ever attended period. Literally. I think the best way to explain why I say this is the name of the conference. The Groovy / Grails Experience.
Groovy is so refreshing! It is NOT a replacement for Java. As Scott Davis said so eloquently “Groovy IS Java and Groovy is NOT Java” How do you argue with logic like that. But seriously. It wouldn’t be that hard to claim that Groovy isn’t really a different language. One could say “It’s just a jar that you add to your classpath that gives you some new APIs and some new syntactical sugar”. Think about things like JSTL and JSP expression language. But when you look at the APIs and syntax goodness that Groovy gives you, you just don’t want to go back. To see more about Groovy take a look at the tutorials and articles on the Groovy website: http://groovy.codehaus.org/Articles
Grails is like a web framework on steroids! With tools like Spring, Hibernate, Ant, SiteMesh, Jetty and so many more built into it, Grails would be great even without Groovy but when you add in the power and flexibility (not to mention sheer joy) of Groovy, this web application development system is almost too good to be true. I have been using Grails for about a year now but at this conference I learned several more things that can be done with Grails. Things like integration with UI tools like YUI, Script.aculo.us that is so easy it should be illegal! Glen Smith's talks were worth the price of admission on their own. Then there was the deep dive into GORM the Grails Object Relational Mapper by Graeme Rocher that was mind-blowing. The more I see of what Grails does for me the happier I am that I get to use it full time. You can do (almost) everything you can do with Grails with Spring and Hibernate by themselves, but it would be so much more work and so much more complexity.
Experience is what set’s all the NFJS conferences apart and this one was no exception. Every detail was taken care of, all the slides were on a 1 gig USB drive that was also very handy for grabbing code samples from speakers after a session. The room sizes and layouts were good, the food was great and refreshments were available throughout the day. This is not a big deal but it’s a very telling point about the difference between NFJS events and other big name conferences. At many other conferences I’ve been at, on the last break of the last day, you’d be lucky to find some cold coffee left over but at the 2GX the last break had plenty of coffee, soft drinks and an ice box full of a variety of ice cream bars. These “little” things really make it easier for you to concentrate on the sessions and the networking opportunities, which were also awesome. The Groovy / Grails community has some of the sharpest developers I’ve met anywhere. With half hour breaks between each 90 minute session and hour to hour and half lunch and dinner breaks, there were many opportunities for those side discussions that make conferences like this so special.
If you weren’t able to make it, don’t worry. They are already planning another one on the west coast in October.
Wednesday, February 20, 2008
In Reston, VA for 2GX
Apart from the excellent learning opportunity, I am also excited about the people that are going to be here. So many of the developers and power users of Groovy and Grails are going to be here. I've read their books, I read their blogs, I read their messages as they help people on the mailing lists, I have even heard some of them on pod casts, but it will be great to actually meet them.
I will try to post throughout the weekend with any interesting tidbits I pickup at the conference.