How to make my sql data available for all new transactions in my Junit?

DarkCrow :

I'm trying to create a Junit test case. I have a create method which is called from my processor method which creates and saves the entity in the new transaction. The problem is the data that I'm loading in my sql is not available for the new transaction.

Processor method:

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

Helper method:

@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;
    }

Factory method:

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:

@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 method:

@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');

Logs:

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)

Even though I have inserted type in my sql its not retrived as the createAndSaveFoo() has created new transaction. How can I get my sql data available for new transaction?

Joel :

Have you tried explicitly setting the transactionMode to ISOLATED within your @sql annotation? That may help to ensure that the inserts are committed before your test method is executed. I.E.

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=25334&siteId=1