java - 如何使我的 sql 数据可用于 Junit 中的所有新事务?

标签 java spring jpa junit

我正在尝试创建一个 Junit 测试用例。我有一个从我的处理器方法调用的创建方法,该方法在新事务中创建并保存实体。 问题是我在 sql 中加载的数据不可用于新事务。

处理器方法:

public void updateFoo(final Test test) throws ProcessingException {
        //Business logics
        Foo foo = this.fooHelper.createAndSaveFoo(test);
        //other business logics
        foo.setName ("Name");
        ...
        ...
    }

辅助方法:

@Transactional(propagation = Propagation.REQUIRES_NEW)
    public Foo createAndSaveFoo(final Test test) throws NotFoundException, BadRequestException {
        if (this.isFooPresent(test)) {
            throw new BadRequestException(LOGGER, "CANNOT_CREATE_FOO", "Foo already created for the test");
        }
        final Foo foo = this.fooDAO.save(this.fooFactory.createFoo(test));
        LOGGER.debug("Foo is saved successfully!, Entity@@ {}", foo);
        return foo;
    }

工厂方法:

public Foo createFoo(final Test test) throws NotFoundException {
     return Foo.FooBuilder.aFoo().
                        withId(test.getId()).
                        withDate((test.getDate()).
                        withSize(test.getSize()).
                        withType(getType(test.getTypeId()).
                        build();
            }

    private Type getType(final int id) throws NotFoundException {
      return this.typeDAO.findById(id).orElseThrow(() -> new NotFoundException(LOGGER, TYPE_NOT_FOUND, "Invalid type id"));
    }

实体:

@Entity
@Table(name = "foo")
public class Foo {

    @Column(name = "id")
    private Long id;

    @Column(name = "date")
    private Date date;

    @Column(name = "size")
    private Long size;

    @ManyToOne
    @JoinColumn(name = "type", foreignKey = @ForeignKey(name = "fk__foo__type_id"))
    private Type type;

    //getters, setters and builders

}

@Entity
@Table(name = "type")
public class Type {

    @Column(name = "id")
    private Long id;

    @Column(name = "date")
    private String name;


    //getters and setters

}

测试方法:

@Test
@Transactional
@Sql(value = {"classpath:sql/create_foo_data.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(value = {"classpath:sql/clean_everything.sql"}, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void foo_test() throws ProcessingException {

        //GIVEN
        Test test = new Test();
        test.setId(12);
        test.setDate(new Date());
        test.setSize(20);
        test.setTypeId(1);

        // WHEN
        this.fooProcessor.updateFoo(test);

        // THEN
        final List<Foo> foo = this.fooDAO.findAll();
        assertEquals(1, foo.size());
        assertEquals(20, foo.get(0).getSize());
        assertEquals("Test2", foo.get(0).getType().getName());


    }

foo_data.sql

INSERT INTO `type` (`id`, `name`) VALUES (0, 'Test1'), (1, 'Test2');

日志:

com.deep.common.core.exception.NotFoundException:  errorCode: 'TYPE_NOT_FOUND' - errorMessage : 'Invalid type id'
    at com.deep.process.factory.entity.FooFactory.lambda$createFoo$0(FooFactory.java:55)
    at java.util.Optional.orElseThrow(Optional.java:290)

即使我在 sql 中插入了类型,它也不会被检索,因为 createAndSaveFoo() 已经创建了新事务。 如何让我的 sql 数据可用于新事务?

最佳答案

您是否尝试过在 @sql 注释中将 transactionMode 显式设置为 ISOLATED?这可能有助于确保在执行测试方法之前提交插入。即:

@Sql(value = {"classpath:sql/create_foo_data.sql"},
    executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD,
    config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))

关于java - 如何使我的 sql 数据可用于 Junit 中的所有新事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60542498/

相关文章:

java - Spring 托 : uploading large files (1GB) via rest controller

java - 如何将已检查的异常从 CompletableFuture 传递到 ControllerAdvice

Tomcat 服务器上的 java.lang.IllegalArgumentException 错误 -SpringMVC

java - 为什么 JPA 有 @Transient 注解?

java - 使用准备好的语句将字段更新到 php 数据库

java - xtext,修改大纲树字符串

java - 如何在 spring 数据 jpa 规范中将枚举作为字符串处理

java - JPA与ORACLE插入空错误

32 位和 64 位操作系统上的 Java 版本

java - Java 是否在 for-each 循环中实习字符串