Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialization of HibernateTransactionManager fails [SPR-4662] #9339

Closed
spring-projects-issues opened this issue Apr 6, 2008 · 4 comments
Closed
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

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

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

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.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

kusuman commented

Hi,
I have implemented the solution proposed by Naaman, but still I getting one more error while I am serializing.

It goes like this

java.lang.RuntimeException: Serialization error. Path to bad object: [com.xyz.cic.bo.report.AutomatedReportDispatcherImpl@132a60, org.springframework.aop.framework.JdkDynamicAopProxy@728b447, org.springframework.aop.framework.ProxyFactory: 2 interfaces [com.xyz.cic.bo.report.AutomatedReportDispatcher, java.io.Serializable]; 1 advisors [org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor: advice bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0']; targetSource [SingletonTargetSource for target object [com.edfenergy.cic.bo.report.AutomatedReportDispatcherImpl@132a60]]; proxyTargetClass=false; optimize=false; opaque=false; exposeProxy=false; frozen=false, [Lorg.springframework.aop.Advisor;@2109e3, org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor: advice bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0', java.lang.Object@11dbed]

is there something else that needs to be done?

Thanks
kusuman

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented May 6, 2009

Juergen Hoeller commented

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).

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Nikolai Holub commented

Had the same issue with Spring 2.0.8 after deployment to clustered environment.
Solution was to eliminate serialization of Spring transactional beans. More about this http://blog.nholub.com/2009/07/spring-transactions-and-serialization.html.

@spring-projects-issues spring-projects-issues added in: data Issues in data modules (jdbc, orm, oxm, tx) type: enhancement A general enhancement labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 3.0 M4 milestone Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants