Home > Enterprise >  Quartz Integration test and transactions
Quartz Integration test and transactions

Time:10-22

I try create integration test on Quartz scheduler.

I have 2 tables: events and tasks. Scheduler create task by event by cron trigger.

@SneakyThrows
@Test
public void taskGenerationBeanTest() {
    RequestData request = requestBuilder(str(), str(), str()).build();
    String orderId = String.valueOf(UUID.randomUUID());
    Event event1 = getEvent("type1", request, orderId);
    Event event2 = getEvent("type2", request, orderId);

    eventRepository.save(event1);
    eventRepository.save(event2);

    Thread.sleep(20000);
    List<Event> events = eventRepository.findAll();
    Thread.sleep(1000);
    List<Task> actual = taskRepository.findAll();

    assertAll(
            () -> assertEquals(2, actual.size()),
            () -> assertTrue(actual.stream().anyMatch(t ->
                    "type1".equals(t.getEvent().getEventType()))),
            () -> assertEquals(event1.getOrderId(), actual.get(0).getEvent().getOrderId())
    );
}

Firstly, I get exception:

could not initialize proxy - no Session

I use this answer Spring Data JPA - "could not initialize proxy - no Session" - With Methods marked as transactional and add spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true to my test config. So now I get another problem - my test sometimes work true, but more often it falls, because it create only 1 task.

Method, that executed by Quartz:

@Override
@Transactional(isolation = Isolation.REPEATABLE_READ)
public int createAndSaveTasks(EventType eventType) {
    List<Task> tasks = eventService.getEvent(eventType)
            .stream()
            .map(Task::new)
            .collect(Collectors.toList());
    taskRepository.saveAll(tasks);
    return tasks.size();
}

So how properly create Integration test with Quarts and transactions?

CodePudding user response:

Test class uses findAll method of repository and if you try to get LAZY initialized method, you can get this exception.

In the assertions :

t.getEvent().getEventType() // can throw it
actual.get(0).getEvent() // can throw it

To avoid it maybe you can make it transactional or eager fetch type can be prefered.

under REPEATABLE READ the second SELECT is guaranteed to display at least the rows that were returned from the first SELECT unchanged. New rows may be added by a concurrent transaction in that one minute, but the existing rows cannot be deleted nor changed.

Difference between "read commited" and "repeatable read"

  • Related