2010-06-12 23 views
5

Estoy intentando Spring 3 (.0.2.RELEASE) y JPA2 e Hibernate 3.5.1-Final ... Una cosa me molesta es que la primavera solo parece aceptar una transacción Manager llamado " transactionManager "Cuando transactionManager no se llama "transactionManager"

Si no lo llamo" transactionManager ", Spring arrojará NoSuchBeanDefinitionException: No se ha definido ningún bean llamado 'transactionManager'.

Aquí es mi 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"/> 

En esta configuración, un administrador de fábrica Entidad es no necesariamente llamado "EntityManagerFactory", y "txAdvice" se no necesariamente llamado "txAdvice", tampoco. Pero no sé por qué en la primavera Spring requiere un administrador de transacciones llamado "transactionManager"?

¿Hay alguna forma de no nombrar a un administrador de transacciones "transactionManager"? (Estoy corriendo múltiples archivos de configuración de la primavera, así que mi mejor esfuerzo para evitar el nombre conflictivos)

código

prueba:

@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); 
    } 
} 

Respuesta

7

Mi entendimiento es que en el contexto de las pruebas unitarias (TransactionalTestExecutionListener) , el código que de lo contrario busca el administrador de transacciones es no usado (TransactionInterceptor#determineTransactionManager).

Puede intentar anotar su clase de prueba con @TransactionConfiguration, que acepta un atributo transactionManager. No es la manera más elegante, pero posiblemente sea la mejor opción por el momento.

+0

¡Gracias! ¡Está resuelto! – smallufo

+0

Pero todavía estoy preocupado si el DAO se inyecta en otro marco (como Wicket), ¿Todavía es posible agregar @TransactionConfiguration al completo del wicket? – smallufo

+0

Tendrás que probarlo para estar seguro, pero * pienso * que en el contexto "real", no necesitarás anotaciones: Spring buscará el transactionManager correcto en función de la id del bean. Sería fantástico si pudieras publicar tus resultados aquí para que la posteridad los vea también. –

3

Hoy, me encontré con el mismo problema cuando estaba tratando un ejemplo muy trivial de Spring-Data JPA. Le había dado un nombre personalizado al administrador de transacciones, "dmTransactionManager". Para solucionarlo tuve que especificarlo, tuve que especificarlo como a continuación:

<jpa:repositories base-package="com.my.repository" transaction-manager-ref="dmTransactionManager"/> 
Cuestiones relacionadas