Recently 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
transactionManager
– An instance of Spring’s HibernateTransactionManager classsessionFactory
– An instance of the Hibernate SessionFactory class- …
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 😉