Trying to destroy beans in the correct order with Spring

It seems to be that the order of destory method calls for non-singleton-scoped beans is completely out of control. From docs (5.1.4 Using depends-on):

The depends-on attribute in the bean definition can specify both an initialization time dependency and, in the case of singleton beans only, a corresponding destroy time dependency

You may create a helper object and delegate creation and destruction of your beans to it:

public class HelperObject
{
    private SessionFactory factory;
    private Session session;
    private Transaction tx;

    public void init()
    {
        session = factory.createSession();
        tx = session.beginTransaction();
    }

    public void destroy()
    {
        tx.commit();
        session.close();
    }

    ...
} 

--

<bean id = "helperObject" class = "HelperObject" scope = "request" init-method = "init" destroy-method = "destroy">
    <property name = "factory" ref = "hibernateSessionFactory" />
</bean>

<bean id="hibernateSession" factory-bean="helperObject" 
    factory-method="getSession" scope="request" /> 

<bean id="hibernateTransaction" factory-bean="helperObject" 
    factory-method="getTransaction" scope="request" />

And, after all, perhaps it is not the best way to manage Hibernate sessions and transactions in Spring. Consider using of Spring's built-in Hibernate and transactions support.

EDIT: Well, the right way to manage transactions is:

  • You don't need request-scoped session and transaction beans
  • You shouldn't call createSession on the session factory returned by org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean. You can inject this session factory into your beans and call getCurrentSession when you need a session, a it will work fine.
  • You can use declarative transaction management (@Transactional annotations on the transactional methods). To make it work you should add to your config:

.

<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="hibernateSessionFactory"/>
</bean>

<tx:annotation-driven/>
  • For more information, see the links above