package com.burtbeckwith.grails.delayds import java.lang.reflect.Field import java.lang.reflect.InvocationHandler import java.lang.reflect.Method import java.lang.reflect.Proxy import org.codehaus.groovy.grails.orm.hibernate.ConfigurableLocalSessionFactoryBean import org.hibernate.SessionFactory import org.springframework.util.ReflectionUtils class DelayedSessionFactoryBean extends ConfigurableLocalSessionFactoryBean { private boolean _initialized private SessionFactory _realSessionFactory @Override void afterPropertiesSet() { // do nothing for now, lazy init in createDelayedSessionFactory() } @Override SessionFactory getObject() { def invoke = { proxy, Method method, Object[] args -> initialize() return method.invoke(_realSessionFactory, args) } return Proxy.newProxyInstance(SessionFactory.classLoader, [SessionFactory] as Class[], [invoke: invoke] as InvocationHandler) } private synchronized void initialize() { if (_initialized) { return } _realSessionFactory = wrapSessionFactoryIfNecessary(buildSessionFactory()) Field field = ReflectionUtils.findField(getClass(), "sessionFactory") field.accessible = true field.set(this, _realSessionFactory) afterSessionFactoryCreation() _initialized = true } }