You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
The text was updated successfully, but these errors were encountered:
This is generally considered as known limitation rather than as bug. We will revisit serializability of Spring-managed resource references as well as of native transaction managers in the Spring 3.0 timeframe.
This should be addressed through #6812 now... A DefaultListableBeanFactory is now serializable when running in an ApplicationContext. Alternatively, consider defining an aop:scoped-proxy element on your transaction manager bean, which as of Spring 3.0 RC1 will lead to serialization of a bean reference only (i.e. not of the full HibernateTransactionManager instance).
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;
}
Affects: 2.5 final
The text was updated successfully, but these errors were encountered: