views:

42

answers:

1

I am trying Spring 3(.0.2.RELEASE) and JPA2 and Hibernate 3.5.1-Final... One thing upsets me is that spring seems only accept a transaction Manager named "transactionManager"

If I don't name it "transactionManager" , Spring will throws NoSuchBeanDefinitionException: No bean named 'transactionManager' is defined.

Here is my config :

<context:component-scan base-package="destiny.data.mining"/>

<context:annotation-config/>

<bean id="miningEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="persistenceUnitName" value="mining"/>
</bean>

<bean id="miningTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" >
  <property name="entityManagerFactory" ref="miningEntityManagerFactory"/>
</bean>

<tx:advice id="txAdviceMining" transaction-manager="miningTransactionManager">
  <tx:attributes>
    <tx:method name="get*"    read-only="true"/>
    <tx:method name="save*"   propagation="REQUIRED"/>
    <tx:method name="update*" propagation="REQUIRED"/>
    <tx:method name="delete*" propagation="REQUIRED"/>
    <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
  </tx:attributes>
</tx:advice>  

<aop:config>
  <aop:pointcut id="methods" expression="execution(* destiny.utils.AbstractDao+.*(..))"/>
  <aop:advisor advice-ref="txAdviceMining" pointcut-ref="methods"/>
</aop:config>

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

In this config , an Entity Manager Factory is not necessarily named "entityManagerFactory" , and "txAdvice" is not necessarily named "txAdvice" , either. But I don't know why on earth Spring requires a transaction manager named "transactionManager" ?

Is there any way not to name a transaction manager "transactionManager" ? (I'm running multiple spring config files , so I try my best to avoid name-conflicting)

test code :

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:mining.xml"})
public class MiningPersonDaoTest
{
  @Inject
  private EntityManagerFactory miningEntityManagerFactory;

  @Inject
  private MiningPersonDao miningPersonDao;


  @Transactional
  @Test
  public void testUpdate()
  {
    MiningPerson p = miningPersonDao.get(42L);
    p.setLocationName("OOXX");
    miningPersonDao.update(p);
    System.out.println(p);
  }
}
+2  A: 

My understanding is that in the context of unit tests (TransactionalTestExecutionListener), the code that otherwise looks up the transaction manager is not used (TransactionInterceptor#determineTransactionManager).

You could try to annotate your test class with @TransactionConfiguration, which accepts a transactionManager attribute. Not the most elegant way, but possibly the best option for the time being.

Lauri Lehtinen
Thank you ! It's solved !
smallufo
But I am still worried about if the DAO is injected into other framework (such as Wicket) , Is it still able to add @TransactionConfiguration to the wicket's compoment ?
smallufo
You'll have to try it out to be sure, but I *think* that in the "real" context, you won't need any annotations - Spring will look up the correct transactionManager based on the bean id. Would be great if you could post your results here for the posterity to see as well.
Lauri Lehtinen