gpt4 book ai didi

mysql - Spring 测试 - 回滚问题

转载 作者:可可西里 更新时间:2023-11-01 07:35:50 25 4
gpt4 key购买 nike

我已经在我的应用程序中创建了 Spring 集成测试。问题是,一个测试没有正确回滚,在数据库中留下了一些东西并导致后续测试失败。

我注意到,如果持久实体是简单实体,则测试效果很好。当实体是继承层次结构的一部分并且继承类型是 InheritanceType.JOINED 类型时,测试失败。当我将其更改为 InheritanceType.SINGLE_TABLE 时,它不会失败。

代码如下:测试类:

 @RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@ContextConfiguration(locations = {"classpath:beans/repository-beans.xml"})
public class OnlyParentRollbackProblemSpringTest {
@PersistenceContext
private EntityManager entityManager;

@Test
//PASSES
public void isDBEmptyTest_1() throws Exception {
Query countQuery = entityManager.createQuery("select count(qi) from " + ParentEntity.class.getSimpleName() + " qi");
int elementsCount = ((Long)countQuery.getSingleResult()).intValue();
assertThat(elementsCount).isEqualTo(0);
}

@Test
//PASSES
public void testThatInfluencesOtherTests() {
ParentEntity queueItem = new ParentEntity();
entityManager.persist(queueItem);
ParentEntity queueItem1 = new ParentEntity();
entityManager.persist(queueItem1);
// given
flush();
// when
Query deleteQuery = entityManager.createQuery("delete from " + ParentEntity.class.getSimpleName());
deleteQuery.executeUpdate();
flush();
// then
Query countQuery = entityManager.createQuery("select count(qi) from " + ParentEntity.class.getSimpleName() + " qi");
int elementsCount = ((Long)countQuery.getSingleResult()).intValue();
assertThat(elementsCount).isEqualTo(0);
}

@Test
//FAILS
public void isDBEmptyTest_2() throws Exception {
Query countQuery = entityManager.createQuery("select count(qi) from " + ParentEntity.class.getSimpleName() + " qi");
int elementsCount = ((Long)countQuery.getSingleResult()).intValue();
assertThat(elementsCount).isEqualTo(0);
}

private void flush() {
entityManager.flush();
entityManager.clear();
}
}

Spring 配置:

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


<context:component-scan base-package="no.mintra.offlinetrainingportal.infrastructure.persistence" />

<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

<bean
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

<tx:annotation-driven transaction-manager="transactionManager" />

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


<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="dataSource" ref="H2DataSource" />
<property name="jpaVendorAdapter" ref="H2JpaVendorAdaptor" />
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.hbm2ddl.auto" value="create-drop" />
</map>
</property>
</bean>

<bean id="H2DataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;MODE=MYSQL;LOCK_MODE=3"/>
</bean>

<bean id="H2JpaVendorAdaptor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.H2Dialect" />
</bean>

实体:

@javax.persistence.Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class ParentEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;

public ParentEntity() {
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}
}

@Entity
public class SecondChildEntity extends ParentEntity {
@Column(unique = true)
@NotNull
private Integer userId;

public SecondChildEntity(Integer userId) {
this.userId = userId;
}

public Integer getUserId() {
return userId;
}
}

和 pom.xml 文件:

<project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>test</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>4.8.1</junit.version>
<org.springframework.version>3.1.0.RELEASE</org.springframework.version>
<log4j.version>1.2.15</log4j.version>
<org.slf4j.version>1.5.8</org.slf4j.version>
<hibernate-core.version>3.6.8.Final</hibernate-core.version>
<hibernate-validator.version>4.1.0.Final</hibernate-validator.version>
<commons-dbcp.version>1.2.2</commons-dbcp.version>
<h2database.version>1.3.163</h2database.version>
<commons-collections.version>3.2.1</commons-collections.version>
<javax.servlet.version>2.5</javax.servlet.version>
<javax.validation.version>1.0.0.GA</javax.validation.version>
<fest.version>1.2</fest.version>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2database.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert</artifactId>
<version>${fest.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
<exclusions>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j.version}</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j.version}</version>
</dependency>


<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework.version}</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<exclusions>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>ejb3-persistence</artifactId>
</exclusion>
</exclusions>
<version>${hibernate-core.version}</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate-core.version}</version>
</dependency>

</dependencies>

最佳答案

此问题特定于 H2 DBMS。

H2Dialect 包含以下警告:

if ( !( majorVersion > 1 || minorVersion > 2 || buildId >= 139 ) ) {
log.warn(
"The {} version of H2 implements temporary table creation such that it commits " +
"current transaction; multi-table, bulk hql/jpaql will not work properly",
( majorVersion + "." + minorVersion + "." + buildId )
);
}

您遇到此问题是因为对具有 JOINED 继承的实体执行批量 delete 涉及创建临时表(请参阅生成的 SQL),以便提交事务的第一部分.

作为解决方法,您可以使用 native SQL 查询而不是批量 HQL delete 查询。或者只使用另一个内存数据库,例如 HSQLDB。

关于mysql - Spring 测试 - 回滚问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8713450/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com