views:

949

answers:

3

I am trying to do spring transactions with @Transactional without any success.

Excerpt from my applicationContext.xml:

<context:annotation-config />
<context:component-scan base-package="hibex" />

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource"
    p:driverClassName="org.postgresql.Driver" p:url="jdbc:postgresql://localhost:5432/hibex"
    p:username="clubspace" p:password="clubspace" />

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation" value="classpath:/hibernate.cfg.xml" />
    <property name="entityInterceptor" ref="beanValidationEventListener" />
</bean>

<!-- a PlatformTransactionManager is still required -->
<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <!--  org.springframework.transaction.jta.JtaTransactionManager
    org.springframework.jdbc.datasource.DataSourceTransactionManager -->
    <property name="dataSource" ref="dataSource" />
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<tx:annotation-driven />

<aop:aspectj-autoproxy />

My full spring config file is here.

And my method, where transactions does not work:

@Transactional
public void m2() {
    OwnerBO owner2 = ownerManager.get(owner.getId());
    owner2.getPets().add(new PetBO("Ubul"));
}

This causes:

1375 [main] ERROR org.hibernate.LazyInitializationException - failed to lazily initialize a collection of role: hibex.bo.OwnerBO.pets, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: hibex.bo.OwnerBO.pets, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
    at org.hibernate.collection.PersistentSet.add(PersistentSet.java:212)
    at hibex.code.Service.m2(Service.java:52)
    at hibex.code.App.run(App.java:15)
    at hibex.code.Main.main(Main.java:14)
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: hibex.bo.OwnerBO.pets, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
    at org.hibernate.collection.PersistentSet.add(PersistentSet.java:212)
    at hibex.code.Service.m2(Service.java:52)
    at hibex.code.App.run(App.java:15)
    at hibex.code.Main.main(Main.java:14)

The service is called from this class:

@Component
public class App {
    @Autowired
    private Service service;
    public void setService(Service service) {
        this.service = service;
    }
    public void run() {
        service.m2();
    }
}

Any ideas?

GenericManager is here: GenericManager on Pastebin

the get method:

public T get(PK id) {
    return dao.findById(id);
}

And the GenericDaoImpl#findById(PK)

public E findById(PK id) {
    return getHibernateTemplate().get(getEntityClass(), id);
}

Thanks

Changelog: Just added additional infos (necessary code snippets)

A: 

The exception is related to Hibernate lazy loading support. It appears that Hibernate session is not open when you are calling owner2.getPets().add(). Could it be that ownerManager.get() is closing the Session ?

Tahir Akhtar
I modified the post to include the `get()` method
pihentagy
"Lazy loading will also just work with an open Hibernate Session, either within a transaction or within OpenSessionInViewFilter/Interceptor. "see http://static.springsource.org/spring/docs/1.2.9/api/org/springframework/orm/hibernate3/HibernateTemplate.html
Tahir Akhtar
You might want to annotate OwnerManager#get method with @Transactional if it isn't already annotated as such.
Tahir Akhtar
+1  A: 

HibernateTransactionManager should be supplied with SessionFactory, see javadoc.

axtavt
So do you say, that I should have `<property name="sessionFactory" ref="sessionFactory" />` in my `transactionManager` bean?
pihentagy
@pihentagy: Yes
axtavt
Ah thanks, that helped me (upvote), but not the _final_ solution for my problem
pihentagy
A: 

Question outdated (dunno how to close the question)

pihentagy