2015-10-03 26 views
1

我试图设置基本的JPA插入测试。但是在数据库中没有保存任何内容。 DB是Postgresql。 Hibernate被用作持久性提供者。使用Spring JPA持久/承诺不能在测试环境中工作JUnit

非常感谢提前。

@Entity 
public class Currency { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    protected Integer id;  

    @Column 
    private String code; 

    @Column 
    private String name; 
... 
} 

的CRUD类:所有测试

@Repository 
@Scope(BeanDefinition.SCOPE_PROTOTYPE) 
@Transactional(propagation = Propagation.REQUIRED) 
public class CRUDServiceBean implements CRUDService { 

     @PersistenceContext(type = PersistenceContextType.EXTENDED) 
     private EntityManager entityManager; 

     public EntityManager getEntityManager() { 
      return entityManager; 
     } 

     public <T extends BaseEntity> T persistAndCommit(T t) { 
      entityManager.persist(t); 
      entityManager.refresh(t); 
      entityManager.getTransaction().commit(); 
      return t; 
     } 

     ... 
     ... 
} 

基类:

@RunWith(SpringJUnit4ClassRunner.class) 
@Configurable(autowire = Autowire.BY_NAME) 
@ContextConfiguration(locations = { "classpath:context-test.xml" }) 
public class BaseTest { 
} 

测试类:

public class CurrencyCreateTest extends BaseTest { 

    @Autowired 
    CRUDService crudService; 

    @Test 
    @Transactional(propagation = Propagation.REQUIRES_NEW) 
    public void createCurrency() throws Exception { 
     Currency currency = new Currency(); 
     currency.setCode("EUR"); 
     currency.setName("Euro"); 
     currency = crudService.persistAndCommit(currency); 
    } 
} 

上下文的test.xml:

<?xml version="1.0" encoding="UTF-8"?> 

<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" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:task="http://www.springframework.org/schema/task" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
      http://www.springframework.org/schema/tx 
      http://www.springframework.org/schema/tx/spring-tx-4.0.xsd 
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context-4.0.xsd">   

    <context:component-scan base-package="com.chartinvest"/> 

    <bean id="contextApplicationContextProvider" class="com.chartinvest.util.ApplicationContextProvider"></bean> 


    <!-- the parent application context definition for the springapp application --> 

    <!-- dataSource --> 
    <bean id="dataSourceFinance" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
     <property name="driverClassName"><value>org.postgresql.Driver</value></property> 
     <property name="url"><value>jdbc:postgresql://localhost/db_finance_test</value></property> 
     <property name="username"><value>postgres</value></property> 
     <property name="password"><value>xxxxxxxx</value></property> 
    </bean> 

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

    <bean id="entityManagerFactory" 
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="persistenceUnitName" value="mypersistenceunit" /> 
     <property name="dataSource" ref="dataSourceFinance" /> 
     <property name="jpaVendorAdapter"> 
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
       <property name="showSql" value="true" /> 
       <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" /> 
      </bean> 
     </property> 
     <property name="jpaPropertyMap"> 
      <map> 
       <entry key="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> 
      </map> 
     </property> 
    </bean> 

    <!-- Enable the configuration of transactional behavior based on annotations -->  
    <tx:annotation-driven transaction-manager="transactionManager"/> 

</beans> 
+0

尝试添加'entityManager.merge(T)'之前,你的'entityManager.persist(T)'在'persistAndCommit' – dazito

+1

是什么意思它不工作?你有错误吗?或者你期望有一些结果,而且它是不同的?请分享预期与实际行为。 –

回答

6

如果测试顺利通过,你没有得到任何的异常,从而使用@TransactionConfiguration(defaultRollback = FALSE)每个测试类或使用@Rollback(假)每个测试方法。 事务性测试将在春季测试上下文中默认回滚。

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={ 
    "test-context.xml"}) 
@TransactionConfiguration(defaultRollback=false) 
@Transactional 
public class SampleCrudTest { 

    @Autowired 
    private SampleCrud sampleCrud; 

    @Before 
    public void onSetUpInTransaction() throws Exception { 
     //Populate Test Data 
    } 


    @Test 
    public void registerSample() { 

     Sample sample = new Sample("foo"); 
     sampleCrud.save(sample); 
     assertNotNull(sample.getId()); 
    } 

} 
+0

我在测试类中添加了@TransactionConfiguration(defaultRollback = false),现在我在表CURRENCY中看到一个新条目。非常感谢您的帮助! – user2023141

+1

请。你可以选择我的答案作为正确的答案,它可以帮助他人解决问题。 –

+0

在我的测试中不起作用。 –

1

我注意到在日志文件中的以下内容:

java.lang.IllegalStateException: Cannot execute getTransaction() on a container-managed EntityManager 
    at 
... 
... 

所以,我删除

entityManager.getTransaction()提交();

从CRUDServiceBean

此方法persistAndCommit(T)中除去该异常,并且没有其他异常了。 测试的输出显示以下内容:

Hibernate: insert into Currency (code, name) values (?, ?) 

但是,没有记录已被写入表货币。

这就像测试完成后,Hibernate删除插入的记录。