@Transactional测试失败

时间:2013-08-22 13:05:59

标签: java spring hibernate spring-transactions spring-test

我尝试为@Transactional创建测试用例。

@ContextConfiguration(locations = {"classpath:/META-INF/spring/app-context.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class TransactionalAnnotationTest {
    public static final BigDecimal PROD_ID = new BigDecimal(1234);

    @PersistenceContext
    HibernateEntityManager em;


    @Test
    public final void testTransactionIsolation() {
        String original = em.find(ProductImpl.class, PROD_ID).getDescription();
        // original = "Foo"
        updateTx(original);
    }

    @Transactional
    public final void updateTx(String original) {
        ProductImpl product = em.find(ProductImpl.class, PROD_ID);
        product.setDescription("Bar");
        whatIsInDB(original);
    }

    private void whatIsInDB(String original) {
        String sameTxDescription = em.find(ProductImpl.class, PROD_ID).getDescription();
        assert !sameTxDescription.equals(original);
    }
}

失败了!第二个em.find是否应该返回带有“Bar”的产品?

2 个答案:

答案 0 :(得分:0)

在设置“description”字段

后尝试显式刷新上下文

product.setDescription("Bar");
em.flush();
whatIsInDB(original);

product.setDescription("Bar"); em.flush(); whatIsInDB(original);

答案 1 :(得分:-1)

嗯,我让它上班了。

  1. 要测试交易:我需要一个简单的em.flush()(感谢@TaoufikMohdit的想法)。如果没有交易,flush()会抛出TransactionRequiredException
  2. @Transactional仅适用于Spring-Managed-Beans。所以我创建了一个服务:

    @Service
    public class BasicTransactionalService {
      @PersistenceContext
      HibernateEntityManager em;
    
      @Transactional
      public void testFlushInTransactional() {
        em.flush();
      }
    
      @Deprecated
      public void testFlushOutsideTransactional() {
        em.flush();
      }
    
      @Transactional
      public void testFlushSubroutineTransactional() {
        testFlushOutsideTransactional();
      }
    }
    
  3. 我将测试更改为:

    @Autowired
    BasicTransactionalService bean;
    
    @Test
    public void testTransactionIsolation() {
      bean.testFlushInTransactional();
    }
    
    @Test(expected = TransactionRequiredException.class)
    @SuppressWarnings("deprecation")
    public void testThrowsTransactionRequiredException() {
      bean.testFlushOutsideTransactional();
    }
    
    @Test
    public void testTransactionalSubroutine(){
      bean.testFlushSubroutineTransactional();
    }
    
  4. 现在工作正常。

    BTW这是我的app-config.xml

    <beans>
      <bean class="BasicTransactionalService" />
      <bean class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" />
      <bean class="org.springframework.orm.jpa.JpaTransactionManager" />
      <tx:annotation-driven />
    <beans>