2010-07-28 16 views
10

He siguiente configuración.@Transactional primavera no se inicia una transacción mientras se prueba con junit4

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx.xsd"> 

<bean id="dataSource" class="org.springframework.jdbc.datasource.IsolationLevelDataSourceAdapter"> 
    <property name="targetDataSource"> 
     <bean class="com.microsoft.sqlserver.jdbc.SQLServerConnectionPoolDataSource"> 
      <property name="user" value="user"/> 
      <property name="password" value="password"/> 
      <property name="serverName" value="someserver"/> 
      <property name="databaseName" value="someDBName"/> 
      <property name="portNumber" value="somePortNumber"/> 
     </bean> 
    </property> 
</bean> 

<!-- this is bean is only used for data extraction module only --> 
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop> 
      <prop key="hibernate.format_sql">true</prop> 
      <prop key="hibernate.show_sql">true</prop> 
     </props> 
    </property> 
</bean> 

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" lazy-init="true"> 
    <property name="persistenceXmlLocation" value="classpath:persistence.xml" /> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="jpaDialect"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/> 
    </property> 
    <property name="jpaProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>     
      <prop key="hibernate.format_sql">false</prop> 
      <prop key="hibernate.show_sql">false</prop> 
      <prop key="hibernate.cache.use_second_level_cache">true</prop> 
      <prop key="hibernate.cache.use_query_cache">true</prop>     
     </props> 
    </property> 
</bean> 

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

<!-- 
    Instruct Spring to perform declarative transaction management automatically 
    on annotated classes. transaction-manager="transactionManager" 
--> 
<tx:annotation-driven transaction-manager="transactionManager"/> 
</beans> 

Entonces, cuando me encontré pruebas de que tenían una instrucción de inserción, que producen mensajes de error como tal:

javax.persistence.TransactionRequiredException: Executing an update/delete query 
    at org.hibernate.ejb.QueryImpl.executeUpdate(QueryImpl.java:47) 

Después de mucha deliberación, he intentado esto:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:services.xml" }) 
@Transactional(propagation = Propagation.REQUIRED) 
@TransactionConfiguration(defaultRollback = true) 
@TestExecutionListeners(value = { DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class}) 
public class SimpleUnitTest { 

    @Test 
    public void simpleTest() throws Exception { 
     System.out.println(entityManager.getTransaction().isActive()); 
     assertTrue(entityManager.getTransaction().isActive()); 
    } 
} 

Y ha fallado. entityManager.getTransaction(). isActive() era de hecho falso.

¿Por qué no prueba transaccional no comienza una transacción?

+0

Parece que tiene una configuración correcta, pero le falta algo. Habilitar los registros, en la mía veo 'DEBUG [AnnotationTransactionAttributeSource] Adición método transaccional 'XXX' con el atributo: PROPAGATION_REQUIRED, ISOLATION_DEFAULT;' en la etapa del contexto de carga y más tarde 'DEBUG [HibernateTransactionManager] Crear nueva transacción con el nombre [XXX]: PROPAGATION_REQUIRED, ISOLATION_DEFAULT' cuando se ejecuta la prueba Así que estoy seguro, la transacción está ahí. –

+0

¿Pudo resolver este problema? – ziggy

+0

¿Ha intentado esto utilizando una plantilla de transacción en lugar de las anotaciones @Transactional? – stringy05

Respuesta

4

Usted tendrá que agregar

@TestExecutionListeners(TransactionalTestExecutionListener.class) 

o extenderse desde

AbstractTransactionalJUnit4SpringContextTests 

para obtener comportamiento transaccional. (recuerde, su clase de prueba no es un bean, por lo que la configuración de transacción normal no se aplica)

+0

Intenté usar esos dos, pero no estoy teniendo mucho éxito. Creo que @RunWith (SpringJUnit4ClassRunner.class) haría que la clase de prueba sea reconocida por Spring de todos modos? ¿No? ¿Cómo debo configurar la prueba para usar las dos que sugirió? –

+0

He editado mi pregunta original para reflejar lo que he intentado después de su sugerencia. –

0

El TransactionalTestExecutionListener está habilitado de forma predeterminada, si usa SpringJUnit4ClassRunner.

Necesitas asegúrese de incluir la configuración de gestión de transacciones en su Prueba contexto config:

@ContextConfiguration(locations = { "classpath:services.xml" }) 

Así se puede comprobar que funciona mediante la inyección del frijol TM:

@Autowired 
private PlatformTransactionManager transactionManager; 

Si la dependencia no se resuelve, entonces la configuración de la transacción no se encuentra correctamente.

Durante la depuración de la prueba, la verificación de la TransactionInterceptor en su StackTrace.

+0

Tengo todo lo que dijo, sin embargo, noté en el registro que no hay rastro de inicio de la transacción. Solía ​​ver el siguiente registro cuando se inicia una transacción: INFORMACIÓN - Comenzó la transacción (1): administrador de transacciones Consulte mi nueva pregunta en: http://stackoverflow.com/q/28669280/353985 – redochka

0

Porque tiene dos respuestas relacionadas con la configuración, supongo que el problema no es la configuración, sino el problema de cómo comprobar si la transacción está activa y cómo se obtiene esa instancia EntityManager.

Un posible problema podría ser: EntityManagerFactory.createEntityManager() método se utiliza en lugar de obtener EntityManager inyectado.

Cuestiones relacionadas