Jippe
Jippe

Reputation: 714

Spring: No transaction manager has been configured

I've been wrestling with this problem for a while, and don't see a solution. Hope anyone can help me.

I have a HibernateTransactionManager configured. However, I see the following message in the log file:

DEBUG [http-8080-1] AnnotationTransactionAttributeSource.getTransactionAttribute(107) | Adding transactional method [cashIn] with attribute [PROPAGATION_REQUIRED, ISOLATION_DEFAULT, -nl.forestfields.picnic.domain.model.exception.IllegalCostException]

DEBUG [http-8080-1] AnnotationTransactionAspect.createTransactionIfNecessary(267) | Skipping transactional joinpoint [nl.forestfields.picnic.view.controller.ShoppingListController.cashIn] because no transaction manager has been configured

Also, in case of an exception, the transaction isn't rolled back.

Here's my configuration:

picnic-servlet.xml:

  <beans>

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

    <tx:annotation-driven />
    .
    .
    .

picnic-context-db.xml:

<bean class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" id="sessionFactory">

    <property name="configLocation" value="classpath:hibernate.cfg.xml" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
        </props>
    </property>
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
    <property name="sessionFactory" ref="sessionFactory" />
 </bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName">
        <value>${hibernate.connection.driver_class}</value>
    </property>
    <property name="url">
        <value>${hibernate.connection.url}</value>
    </property>
    <property name="username">
        <value>${hibernate.connection.username}</value>
    </property>
    <property name="password">
        <value>${hibernate.connection.password}</value>
    </property>
</bean>

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

The code that should be executed inside a transaction:

@Transactional(rollbackFor=IllegalCostException.class)
public ModelAndView cashIn(@RequestParam final Long id) throws IllegalCostException, llegalOrderStateException, IllegalShoppingListStateException {

  final ShoppingList shoppingList = shoppingListRepository.getById(id);
  shoppingList.cashIn();
  shoppingListRepository.add(shoppingList);

  return new ModelAndView(...);
}

Can anyone see the problem?

Cheers, Jippe

Upvotes: 2

Views: 7869

Answers (5)

lordblack
lordblack

Reputation: 11

to solve the prolem, you have to declare :

<tx:annotation-driven />

into picnic-context-db.xml and not in picnic-servlet.xml

lrdblck

Upvotes: 1

Kai Moritz
Kai Moritz

Reputation: 621

Try changing

`<tx:annotation-driven />

   to 

<tx:annotation-driven transaction-manager="transactionManager" />

Couldn't find any other problem here.

This cannot be the solution, because the spring-documentations says:

You can omit the transaction-manager attribute in the tag if the bean name of the PlatformTransactionManager that you want to wire in has the name transactionManager. Using @Transactional

Something else must have changed...

Upvotes: 0

skaffman
skaffman

Reputation: 403591

You say you have two different bean definition files. Do these represent two different application contexts, or does one import the other?

The spring docs aren't clear on this, but it may be that will only auto-locate the "transactionManager" bean if it's in the same context as itself. If the transactionManager is in the parent context, it may not find it.

As jerrish said, just explicitly specify the transaction-manager attribute of the element.

Upvotes: 0

Miguel Ping
Miguel Ping

Reputation: 18347

Also, rollback only occurs for Unchecked Exceptions. If you want to rollback for Checked Exceptions, you'll have to declare it in the @Transactional annotation:

@Transactional(rollbackFor = { IllegalCostException.class, llegalOrderStateException.class })
public ModelAndView cashIn(@RequestParam final Long id) throws IllegalCostException, llegalOrderStateException, IllegalShoppingListStateException {

  final ShoppingList shoppingList = shoppingListRepository.getById(id);
  shoppingList.cashIn();
  shoppingListRepository.add(shoppingList);

  return new ModelAndView(...);
}

Upvotes: 2

Jerrish Varghese
Jerrish Varghese

Reputation: 581

Try changing

<tx:annotation-driven />
       to
<tx:annotation-driven transaction-manager="transactionManager" />

Couldn't find any other problem here.

Upvotes: 7

Related Questions