Java 使用Spring JPA JUnit在测试环境中持久化/提交不起作用
我正在尝试设置一个基本的JPA插入测试。但数据库中没有保存任何内容。 DB是Postgresql。Hibernate用作持久性提供程序 非常感谢Java 使用Spring JPA JUnit在测试环境中持久化/提交不起作用,java,spring,hibernate,jpa,junit,Java,Spring,Hibernate,Jpa,Junit,我正在尝试设置一个基本的JPA插入测试。但数据库中没有保存任何内容。 DB是Postgresql。Hibernate用作持久性提供程序 非常感谢 @Entity public class Currency { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) protected Integer id; @Column private String code; @Column
@Entity
public class Currency {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Integer id;
@Column
private String code;
@Column
private String name;
...
}
积垢类:
@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;
}
...
...
}
测试类:
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);
}
}
context-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>
org.postgresql.Driver
jdbc:postgresql://localhost/db_finance_test
博士后
xxxxxxxx
我注意到日志文件中有以下内容:
java.lang.IllegalStateException: Cannot execute getTransaction() on a container-managed EntityManager
at
...
...
所以,我删除了
entityManager.getTransaction().commit()
来自CRUDServiceBean中的persistAndCommit(T)方法
这删除了异常,不再有其他异常。
测试的输出显示以下内容:
Hibernate: insert into Currency (code, name) values (?, ?)
但是,尚未使用表CURRENCY写入任何记录
就像测试完成后,Hibernate删除插入的记录一样 如果您的测试成功通过,并且没有得到任何异常,那么请对每个测试类使用@TransactionConfiguration(defaultRollback=false),或者对每个测试方法使用@Rollback(false)。 在spring测试上下文中,事务测试默认情况下将回滚
@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());
}
}
您可以使用@Rollback(false)
e、 g:
这对我来说很有效,请确保启动事务并提交事务
public Transaction startTransaction(Session session) throws HibernateException {
return session.beginTransaction();
}
...... your test code goes here......
public void endTransaction(Session session) throws HibernateException {
if (session != null) {
session.getTransaction().commit();
}
}
尝试将
entityManager.merge(t)
添加到entityManager.persist(t)
之前的persistAndCommit
中,这意味着它不起作用?你有错误吗?或者,你期望得到一些不同的结果吗?请分享预期与实际的行为。我在测试类上添加了@TransactionConfiguration(defaultRollback=false),现在我在表CURRENCY中看到了一个新条目。非常感谢你的帮助!!!请您可以选择我的答案作为正确答案,这有助于其他人解决问题。@现已弃用。使用@Transactional(Transactional.TxType.REQUIRES_NEW)
@Rollback(false)
@DataJpaTest
@RunWith(SpringRunner.class)
@Rollback(false)
abstract class RepositoryTest {
...
}
class UserReportitoryTest extends RepositoryTest {
@Autowired
UserRepository repository;
@Test
void it_should_save_the_user() {
repository.save(user);
}
}
public Transaction startTransaction(Session session) throws HibernateException {
return session.beginTransaction();
}
...... your test code goes here......
public void endTransaction(Session session) throws HibernateException {
if (session != null) {
session.getTransaction().commit();
}
}