tzortzik
tzortzik

Reputation: 5133

spring @Transactional is not rolling back

I have a similar piece of code inside a @Service:

@Autowired
private MyDAO myDAO;

@Transactional
@Override
public void m(...) {
    Integer i = null; // this is just to simulate a NPE
    myDAO.saveX(...);
    i.toString(); // throws NullPointerException
    myDAO.saveY(...);
}

This piece of code throws a NPE which is not catched by Spring and so my code is not rolled back. Any idea why is this happening?

I have the same configuration as in other places in my app and in those places it works as expected.

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

Upvotes: 1

Views: 2951

Answers (3)

Evgeni Dimitrov
Evgeni Dimitrov

Reputation: 22516

Possible reasons:

  1. Your bean is not managed by Spring, a.k.a created with new instead of taken from the application context.

  2. you're calling the m() method in another method of the same class/bean. By default Spring uses proxies to manage declarative transactions and internal calls are not supported.

  3. you're throwing checked exception and not using @Repository on the dao. Declarative transactions work only for runtime exceptions. @Reposiotry "fixes" that by wrapping all exceptions in a DataAccessException. (probably not the case since NPE is runtime)

Upvotes: 4

tzortzik
tzortzik

Reputation: 5133

I found the solution here. I have multiple contexts and some of them didn't have <tx:annotation-driven />.

Upvotes: 1

Pavoletto
Pavoletto

Reputation: 140

Try adding rollbackFor parameter to @Transactional annotation

@Transactional(rollbackFor=NullPointerException.class)

Upvotes: 1

Related Questions