Tuesday, November 23, 2010

Case Insensitive withCriteria

I found this easy way to do a case insensitive query on the DB using with Criteria. Unfortunately Grails documentation does not mention this, but remember you are using Hibernate. So using .ignoreCase() on the eq works perfectly.


 personList = Person.withCriteria {
  if (params.firstName)
   eq('firstName', params.firstName).ignoreCase()
  if (params.lastName)
   eq('lastName', params.lastName).ignoreCase()
  if (params.login)
   eq('login', params.login).ignoreCase()
  if (params.personHashId)
   like('personHashId', params.personHashId)
  maxResults(Constants.SEARCH_MAX_RESULTS)
 }

Wednesday, November 3, 2010

Elvis Operator

Is really neat and not used enough. Basically it is a modified ternary.
Here is and example for returning a sensible value if an expressions resolves to null (or false).
    def a = b ?: "No Value"
In that example a should equal b unless b is null or false, then it would be assigned "No Value"

Monday, October 18, 2010

Service and DB connection pools

(From Kwang Ho-Lee's investigations)

When using a Grails service that is transactional (default) and it uses the DB, the service will try and get a connection to the DB from the pool each time it is called.
So it is a bad idea to have code in a controller that calls a service in a loop. The loop should really be in the service, this will prevent multiple connections being made, plus it makes better design sense.

Wednesday, October 13, 2010

Time durations

Some code that shows durations and works nicely as a timer
    import groovy.time.*

    def timeStart = new Date()
    // Some code you want to time
    def timeStop = new Date()
    TimeDuration duration = TimeCategory.minus(timeStop, timeStart)
    println duration
This will give you the time in hours, minutes, seconds

Monday, September 27, 2010

Great tool

Found a nice tool to track down exactly what XML/SOAP your grails app is building. If you run your application locally you can easily see the outbound XML by using this tool.

HttpAnalyzer

Monday, September 13, 2010

Using the Grails Console

Thanks to Kwang Ho Lee for this

Using the console is very powerful, your console actually runs within your current
environment so it is a very powerful place to rapidly prototype code.

Start the console with something like this, allows you to attach to any environment
  @echo off
  set JAVA_OPTS=-Xmx1024m -XX:MaxPermSize=256m
  grails -Dgrails.env=dev console

Then from within the console you have access to domain objects and the service objects. Just import domain objects and do a getBean to obtain the service objects

  import domain.*
  def aService = grailsApplication.mainContext.getBean('aService')
  def dlr = Dealer.findByDealerId('XXX')
  def qs = aService.bigFinder(dlr)

Sunday, August 22, 2010

Paginations to list

Grails has a great way of paginating domain object lists. It is just build in an works well.
But I had a list object that I needed to pagination, so I found this great post

List.metaClass.paginate = { max, offset=0 ->
  delegate.subList( offset, Math.min( offset + max, delegate.size() ) )
}
 
def list = (1..30).toList()
assert list == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 
  18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
assert list.paginate( 5, 7 ) == [8, 9, 10, 11, 12]
assert list.paginate( 5 )    == [1, 2, 3, 4, 5]
assert list.paginate( 5, 0 ) == [1, 2, 3, 4, 5]
assert list.paginate( 5, 1 ) == [2, 3, 4, 5, 6]

Saturday, August 21, 2010

Distinct selection

Found a nice way of doing a distinct sql selection using the Gorm criteria.
You just use a critera and a projections (hibernate)
        def criteria = DomainObj.createCriteria()
        def date = new Date()
        def list = criteria {
            and {
                gt('endDate', date)
                lt('beginDate', date)
            }            
            projections {
                distinct('term')
            }
        } 

Friday, August 20, 2010

Lazy Initialization Error

Beware of passing domain objects around. If you pass a domain object to other functions, and then try and traverse the associations (many-many, one-one) sometimes you can get into a situation where you get a Lazy Initialization error. This is because Domain objects are by default loaded lazily (more info).

You can get around this
  • By actually reloading the domain object in each function, although this may seem slow, hibernate will cache these calls (if you allow it)
  • You can turn the associations in the Domain object to fetch eagerly (though this may have a performance hit, as more of the object is loaded)
  • You can use a constraints() load to specifically eager fetch you required relationships (see Querying with eager fetching)

Wednesday, August 18, 2010

Spaceship operator

When making a sort closure, use the spaceship operator to allow for sorting where their might be nulls.
A more detailed explanation can be found here


// This does not work
[0, 1, null, 'a'].sort{a,b-> a > b}

// This sorts fine
[0, 1, null, 'a'].sort{a,b-> a <=> b}

Command Objects and validation

Domain objects and their constraints are great. But what if you have relatively complicated domain objects but have a page where you want specific validation, that is not tied to the domain object.
Command Objects are a great way to handle this.
At the bottom of your controller add a command object. Then you can use this command object in your controller. (Unverified, but it seemed if the command object was at the top of the controller the hot reloading stopped working)


class MyController {
def save = {MyCommand ->

// This will validate the command object based on its constraints
cmd.hasErrors()
}
}

class MyCommand {
Boolean switch
String value

static constraints = {
switch(nullable:false)
value(nullable:false)
}
}


And of course the command object has all the constraints available to it. So if you wanted value to be mandatory only if switch it true, do something like this


class MyCommand {
Boolean switch
String value

static constraints = {
switch(nullable:false)
value(validator: {val, obj->
if (obj.properties['switch'])
val ? true : ['default.null.message']
})
}
}

Hello world

I am a developer on a large high profile Grails project.
We have a team of about 4-12 developers.

I hope to use this blog to post some snippets of grails and groovy goodness. Please note some of the snippets may have errors because for privacy reasons I cannot just copy my code from the project.

We currently run Grails 1.6.7
And develop primarily in STS IDE