Brain Flush

July 31, 2008

Grails Quick Tip #2: Getting Access to SessionFactory and MessageSource

Filed under: Software Development & Programming — Tags: , — Matthias @ 9:52 am

Sometimes it is necessary to reach beyond the dynamics of Grails’ finder methods and other injected features, and instead make use of the underlying objects that implement this behavior directly. An example would be the need to access a Hibernate session directly, maybe because  you are writing a service object in plain Java, which means none of the features that rely on the dynamic nature of Groovy are available to you. These include:

  • the current Hibernate session
  • the Spring message source for accessing text in various translations
  • a logger object

All these objects are injected by Grails into your services automatically — that is, if you follow the conventions and are programming in Groovy. If you’re not, you’re pretty much on your own, because the Grails reference guide does not make any mention of these objects and how to access them.

However, I figured they’d be simply Spring beans as well (with the exception of log objects, see below), and due to the consistent conventions in Grails I soon discovered that they are called sessionFactory and messageSource respectively. So in order to access them directly from within a Groovy service object, just do this:

class MyService {
   def sessionFactory
   def messageSource

   def serviceMethod = {
      def session = sessionFactory.getCurrentSession()
      ...
   }
}

That doesn’t work with Java services of course. In that case, go to resources.groovy and add a bean declaration:

 myService(com.example.services.MyService) {
    sessionFactory = ref("sessionFactory")
    messageSource = ref("messageSource")
 }

Note that log objects have to be created manually, because they are not handled by the Spring container. You could for instance create a Log4J object, as shown below. Do not forget to add the setters for the Spring beans, so Grails can set them for you automatically:

import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.springframework.context.MessageSource;

public class MyService {
    // instantiates a Log4J logger object
    private Logger log = Logger.getLogger(getClass().getName());

    // a Hibernate SessionFactory
    private SessionFactory sessionFactory;

    // a Spring MessageSource
    private MessageSource messageSource;

    [...]

    // used by the Spring IoC container to inject the session factory bean
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    // used by the Spring IoC container to inject the message source bean
    public void setMessageSource(MessageSource messageSource) {
        this.messageSource = messageSource;
    }
}

It may be a good idea to use a class like this as a base class for all your plain Java services, so they can benefit from these objects, too.

About these ads

7 Comments »

  1. Thanks for this tip – incredibly helpful, but I was wondering what you mean by ‘log objects need to be created manually’, is it possible to tell us how you do that?

    Comment by cliftonc — August 19, 2008 @ 7:39 am

  2. Hi cliftonc,

    I have updated the text to contain an example service class written in Java, which also instantiates a Log4J logger (the Grails libraries already include Log4J, so no additional setup should be necessary).

    You would then use this log object pretty much the same way as the log object Grails injects into your Groovy services.

    Hope that helps.

    Comment by Matthias — August 19, 2008 @ 10:34 am

  3. One more thing:

    If you work on a Hibernate session directly, that is contrary to e.g. using the methods Grails injects into your domain objects (like save(), delete(), refresh() etc.), do not close the session in a finally-block after retrieving it via sessionFactory.getCurrentSession().

    This is because the session lifetime in Grails is bound to the lifecycle of a Controller (which usually is that of a single request), and within these boundaries the session is shared between objects. If you close the session in one object, any other calls (be it from Groovy or Java code) that somehow involve DB access via Hibernate will fail (unless of course they create a new session in their own scope).

    Comment by Matthias — August 19, 2008 @ 10:43 am

  4. thx a looottt
    i looking for this tips for many days :)

    but i found that

     def messageSource ; 

    wont work in Controller …

    Comment by Adwin — November 18, 2008 @ 12:24 pm

  5. It certainly works in controllers as well; it will work in services, controllers, and domain objects. Can you post the exact code fragment where it did not work for you?

    Comment by Matthias — November 18, 2008 @ 1:35 pm

  6. In fact, it should work in ANY Spring managed entity. “def myBean” ist simply Grails’ way of defining a dependency to a Spring managed object called “myBean”.

    Comment by Matthias — November 18, 2008 @ 1:38 pm

  7. [...] Grails Quick Tip #2: Getting Access to SessionFactory and MessageSource « Brain Flush – [...]

    Pingback by Game g = new Game(); » Bookmarks for October 18th through October 28th — October 28, 2009 @ 5:05 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Shocking Blue Green Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 37 other followers

%d bloggers like this: