views:

179

answers:

2

I have grails project using my existing Java domain classes of a spring project and I need to configure typeDefinitions. In the spring project it is possible to configure this property of the LocalSessionFactoryBean - but how do you do that in a grails project?

+1  A: 

The Grails version of LocalSessionFactoryBean is a subclass, org.codehaus.groovy.grails.orm.hibernate.ConfigurableLocalSessionFactoryBean. It's registered as a Spring bean in org.codehaus.groovy.grails.plugins.orm.hibernate.HibernatePluginSupport as

sessionFactory(ConfigurableLocalSessionFactoryBean) {
   ...
}

so you have a couple of options. One is to redefine the bean in resources.groovy, maintaining what Grails configures plus your changes, i.e.

sessionFactory(MyCustomConfigurableLocalSessionFactoryBean) {
   ...
   typeDefinitions = ...
}

or if possible you can reference the bean and modify it in BootStrap:

class BootStrap {

   def sessionFactory

   def init = { servletContext ->
      sessionFactory.foo = bar
   }

   def destroy = {}
}

It looks like typeDefinitions need to be configured early, while the factory bean is building the SessionFactory, so option 1 is probably your best bet.

Burt Beckwith
this seems like the right way to achieve what I want but I have to admit that my grails knowledge is not as good as my spring knowledge - so could you please give me a tip on how to "redefine the bean in resources.groovy, maintaining what Grails configures plus your changes"?
Thomas Einwaller
+1  A: 

another option is to use spring's life-cycle callbacks, e.g. implementing a BeanPostProcessor

public class CustomBeanPostProcessor implements BeanPostProcessor {

// simply return the instantiated bean as-is
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    return bean; // we could potentially return any object reference here...
}

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if ("sessionFactory".equals(beanName) && bean instanceof ConfigurableLocalSessionFactoryBean)  {
        ConfigurableLocalSessionFactoryBean sessionFactory = (ConfigurableLocalSessionFactoryBean) bean;
        sessionFactory.setTypeDefinitions(...);
    }
    return bean;
}

}

and throw it to your resources.groovy

customProcessor(CustomBeanPostProcessor)

this way you don't have to redefine the sessionFactory bean thats already wired into GORM dynamic finders et.al.

Andre Steingress
nice suggestion, the problem is that postProcessAfterInitialization is never called for a bean named sessionFactory or an instance of ConfigurableLocalSessionFactoryBean :-(
Thomas Einwaller
did you add the bean definition to your resources.groovy? i've tested the code above and setting TypeDefinitions did work that way.
Andre Steingress
I found out why this does not work for my situation: sessionFactory can't be instantiated because it fails when loading the mapping information - because it does not know the configured UserType.So I need to configure these TypeDefinitions before the sessionFactory is instantiated
Thomas Einwaller
why don't you specify the type-definitions through Hibernate's <typedef> element or annotation?
Andre Steingress