Grails Expert Tip #8 – There’s a Bean for That

grails-expert-tipRecently I code reviewed some of the Grails (2.4.5) code of another team (of course :-)) and here’s a snippet I came across.

In some “search helper service”:

 public int countListWithoutFetching(Collection collection) {
   def session = grails.util.Holders.grailsApplication.mainContext.sessionFactory.currentSession
   return ((Integer) session.createFilter(collection, "select count(*)" ).list().get(0)).intValue()
 }

This team somehow needed some ‘generic’ way of counting the amount of records in the database, I thought.

First questions which popped up were: what can be put in the passed collection? Why the elaborate way of getting the current Hibernate Session? Why and how is createFilter used here?

I had some code review comments about this particular piece of code.

Inject beans, don’t look em up

In non-static contexts there’s no need to get the singleton GrailsApplication through the Holders class with the static method getGrailsApplication(). You can always inject grailsApplication in another Spring bean (e.g. controller or service).

“Holder” classes, such as grails.utils.Holders and org.springframework.web.context.request.RequestContextHolder, usually expose stuff through static methods which can be conveniently called from almost any location – which at the same time are consequently over-used by most beginning developers.

Use the beans already available

Next to that, there’s usually no need to get the current Hibernate Session through Spring’s ApplicationContext using grailsApplication.mainContext.

Grails shipped with the Hibernate plugin, which already exposes some beans such as

Just inject sessionFactory in your service.

def sessionFactory
public int countListWithoutFetching(Collection collection) {
   def session = sessionFactory.currentSession
   ...
}

Done.

If you’re wondering what the deal is with the session.createFilter construction – I’ll get back on that 😉

One thought on “Grails Expert Tip #8 – There’s a Bean for That

Comments are closed.