|
From: Arnout E. <sp...@bz...> - 2007-12-13 14:11:30
|
Hi,
The Hibernate *SessionFactoryBean contain a hibernate.cfg.Configuration,
and in some cases it can be useful to have access to that object from
the application. This isn't currently possible because the
AbstractSessionFactoryBean returns the SessionFactory with getObject(),
so the application only has access to the SessionFactory, not to the
*SessionFactoryBean itself.
I wrote a simple workaround for that, allowing one to create an
'ExposedSessionFactoryBean' in exactly the same way you'd normally make
e.g. an AnnotationSessionFactoryBean:
public interface ExposedSessionFactoryBean {
Configuration getHibernateConfiguration();
SessionFactory getHibernateSessionFactory();
}
Implementation (for AnnotationSessionFactoryBeans):
public class ExposedAnnotationSessionFactoryBeanImpl extends
AnnotationSessionFactoryBean
implements ExposedSessionFactoryBean {
/** Work around getConfiguration being protected final */
public Configuration getHibernateConfiguration()
{
return getConfiguration();
}
/** Work around getSessionFactory being protected final */
public SessionFactory getHibernateSessionFactory()
{
return getSessionFactory();
}
/** 'expose' ourselves instead of returning the SessionFactory */
@Override
public Object getObject() {
return this;
}
/** 'expose' ourselves instead of returning the SessionFactory */
@Override
public Class getObjectType() {
return getClass();
}
}
With getHibernateSessionFactory(), a simple 'glue' bean can be written
which takes the ExposedSessionFactoryBean and yields the SessionFactory,
just like a normal *SessionFactoryBean would do:
public class SessionFactoryGetter implements FactoryBean {
private ExposedSessionFactoryBean sessionFactoryBean;
public ExposedSessionFactoryBean getSessionFactoryBean() {
return sessionFactoryBean;
}
/** inject */
public void setSessionFactoryBean(ExposedSessionFactoryBean
sessionFactoryBean) {
this.sessionFactoryBean = sessionFactoryBean;
}
/** fetch the SessionFactory from the ExposedSessionFactoryBean */
public Object getObject() {
return sessionFactoryBean.getHibernateSessionFactory();
}
/** publish the type of the sessionfactory */
public Class getObjectType() {
// this may be called before the sessionFactoryBean is injected,
so we just
return SessionFactory.class;
}
public boolean isSingleton() {
return true;
}
}
This way, the applicationContext can remain reasonably clean: the
exposedHibernateSessionFactory is configured exactly as you'd normally
configure you hibernateSessionFactory:
<bean id="exposedHibernateSessionFactory"
class="nl.topicuszorg.somepackage.ExposedAnnotationSessionFactoryBeanImpl">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<!-- more config here -->
</bean>
And the hibernateSessionFactory is created from that
exposedHibernateSessionFactory:
<bean id="hibernateSessionFactory"
class="nl.topicuszorg.hibernate.spring.orm.SessionFactoryGetter">
<property name="sessionFactoryBean"
ref="exposedHibernateSessionFactory"/>
</bean>
This seems useful to me, and I'd like to make it more widely available.
Does this solution make sense technically? Are there neater ways to
achieve this? If this seems all-right, I suppose I should prepare it as
a patch against spring CVS HEAD and submit it to JIRA?
Regards,
Arnout
|