Skip to content

Serialization of HibernateTransactionManager fails [SPR-4662] #9339

@spring-projects-issues

Description

@spring-projects-issues

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

Metadata

Metadata

Assignees

Labels

in: dataIssues in data modules (jdbc, orm, oxm, tx)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions