草庐IT

mysql - Spring 测试 - 回滚问题

coder 2023-10-11 原文

我已经在我的应用程序中创建了 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/

有关mysql - Spring 测试 - 回滚问题的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  3. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  4. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  5. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  6. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  7. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  8. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  9. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  10. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

随机推荐