Monday, March 22, 2010

Calling Stored Procedures in Groovy

As expected, Groovy provides some compact syntax for calling stored procedures. All the magic is contained in the Sql class.

For example, a stored procedure with the following signature:
insert_book(p_title IN VARCHAR2, p_author IN VARCHAR2, p_isbn OUT VARCHAR2, p_id OUT INTEGER)


Can be invoked with the following Groovy code:
public saveBook(book) {
def isbn
def bookId

Sql sql = new Sql(dataSource)
sql.call "{insert_book(?, ?, ?, ?)}",
[book.title, book.author, Sql.VARCHAR, Sql.INTEGER],
{ spIsbn, spId ->
isbn = spIsbn
bookId = spId
}
}

Note:
  • the first parameter is a string containing the stored proc call that also parameterizes the in/out variables.
  • the second parameter are the variables to be passed in or the corresponding type of the out parameter
  • the third parameter is a closure that is given the out parameters of the executed stored procedure in the order they are declared in the sproc.
dataSource is an instance of the data source created in DataSource.groovy. Our snippet assumes the saveBook method is contained in a spring bean, where the dataSource variable can be automatically injected.


More information on Groovy and db objects can be found here.

Thursday, March 4, 2010

Mapping Domain Classes with Hibernate Annotations

Save the following file as grails-app/conf/hibernate/hibernate.cfg.xml. Note that it specifies a single class being mapped, all classes in a package can be specified by using:

<mapping package="com.test.domain" />


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>

<session-factory>
<mapping class="Firm"/>
</session-factory>

</hibernate-configuration>

Our domain class looks as follows. Note that the table name is a Oracle Database Link.

import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.Id
import javax.persistence.Table

@Entity()
@Table(name="firm@remote")
class Firm {
@Id
Integer id
@Column(name="name")
String name
@Column(name="status")
String status

@Column(name="key")
String key
@Column(name="short_name")
String shortName
}

Wednesday, March 3, 2010

Grails Unit Testing for Beginners

When you use grails generators for domain classes, controllers, services or portlets, it automatically creates tests for you. Simply running "grails test-app" will run all unit and integration tests and is great for build processes. However, when you're developing you simply want to invoke the tests of the class you're editing. This can be accomplished by passing arguments to test-app like this:

grails test-app MyService -unit

or

grails test-app MyController -integration

Using println for testing is bad form but many times println in the code or tests is helpful for debugging. Grails generates test reports and one of them is the System.out. Open a tail tool (such as Baretail for Windows) on the file and you'll see the new results everytime the test runs (it does delete and replace the file.) These are located in:

my-app-home\target\test-reports\plain\
TEST-unit-unit-MyServiceTests.txt
TEST-unit-unit-MyServiceTests-err.txt
TEST-unit-unit-MyServiceTests-out.txt

You can also view an html report on the results of your tests. This is useful for seeing stacktraces:
my-app-home\target\test-reports\plain\index.html



-Ben Hidalgo

Tuesday, March 2, 2010

Input for One-to-Many Relationships Revisited

In our previous post, we discussed a method for logically displaying and constructing objects in a one to many relationship. However, this was not ideal - a lot of display logic was being written in the taglib, and writing html in code is painful and plain ugly. While this problem can be overlooked when only one additional text input was being displayed, a new feature which requires the display of a full domain object forces us to re-examine our approach.

Our solution uses templates and the ability to pass code to taglibs. Any content written within the tag is passed to the taglib in the 'body' parameter. This content, which can be additional html, a closure, or a template, can then be invoked within the taglib as a method.

Our example is a student report card: each report card has at most one class in a particular category, though it is not required to have a class in every category. First, we have the domain on the many end of the relationship.
class CourseCategoryType {
String category
String status

static constraints = {
category(inList:['History', 'Civics' ,'Math', 'Science', 'Art'])
status(inList:['Active', 'Inactive'])
}
}
class Course {
CourseCategoryType courseCategoryType
String name
String courseCode
BigDecimal gpa
}


Next we have the taglib. Notice we are invoking body as a method, and passing a parameter. The parameter will be available to the content of body as the variable 'it'.
class CourseTagLib {
def courseTag = {attrs, body ->
def from = attrs.from
def courses = attrs.courses

from.each {
def course
// find if the course has been selected
for (Course c: courses) {
if (c.courseCategoryType.id == it.id) {
course = c
}
}

// build parameters to pass to the template
def params = [
courseCategory: it,
course: course
]
out << body(params)
}
}
}


Finally we have the gsp snippet which calls our taglib. Notice that the template is passed 'it' as the bean. Remember, any information passed to body in the taglib is referenced by 'it'.
<g:courseTag from="${CourseCategoryType.findAllByStatus('Active')}" 
courses="${reportCardInstance.courses}">
<g:render template="course" bean="${it}" />
</g:courseTag>


The template is the Grails generated create gsp with a few changes
1. It's been renamed to _course.gsp
2. The bean being used is different than the default generated template - it is no longer an instance of Course, it is the array passed by the taglib. The bean is also named 'it'. Thankfully, these are cut-and-paste changes.

The disadvantage of our new method is that we're tightly coupling the taglib and template to a domain class; there is no possibility of reuse. However, the taglib is relatively simple to create - it is essentially massaging data into a format to be used by the template.

Monday, March 1, 2010

Object Marshalling and Transients Fields

By default, the converters found in the grails.converters package only marshal persistent fields on domain objects. To override this behavior, use GroovyBeanMarshaller instead. It comes in 2 flavors, XML and JSON.

example:
grails.converters.JSON.registerObjectMarshaller(Contact, {o, c ->
new org.codehaus.groovy.grails.web.converters.marshaller.json.GroovyBeanMarshaller().marshalObject(o, c)
})