-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Description
Naaman Lifshitz opened SPR-4662 and commented
The HibernateTransactionManager class is Serializable (via its super-class), but holds a non-transient reference to a DefaultListableBeanFactory instance, which is not Serializable. As a result, when trying to serialize objects proxied for transactions, a NotSerializableException is thrown. (It also holds a non-transient reference to a DataSource).
From the source-code as well as from the javadocs, I understand that the TransactionInterceptor class was designed for serialization (as well as proxies in general) . However, in its writeObject method it attempts to serialize the transactionManager as is, which in the case of the HibernateTransactionManager, throws the exception.
This seems to me like a bug. The implication of the problem is that it is impossible to deploy in a cluster that employs session-replication. However, since there is a workaround I prioritize this as - Minor.
This is a workaround:
public class SerializableHibernateTransactionManager extends HibernateTransactionManager
implements ApplicationContextAware
{
private static ApplicationContext applicationContext;
private Object writeReplace() throws ObjectStreamException
{
logger.debug("<serialized>");
/*
* null the non-transient references to these non-serializable objects
* before serialization (so that serialization does not fail).
*/
super.setBeanFactory(null);
super.setDataSource(null);
return this;
}
private Object readResolve() throws ObjectStreamException
{
logger.debug("<deserialized>");
/*
* discard the de-serialized object, since it is missing the beanFactory and dataSource,
* and obtain the bean from Spring, and return it instead. This is ok, since it is stateless.
*/
return BeanFactoryUtils.beanOfTypeIncludingAncestors(applicationContext, HibernateTransactionManager.class);
}
public void setApplicationContext(ApplicationContext applicationContext)
{
SerializableHibernateTransactionManager.applicationContext = applicationContext;
}
}
Affects: 2.5 final