Транзакционный не откат, хотя правило соответствует - PullRequest
0 голосов
/ 29 апреля 2020

В настоящее время я пытаюсь реализовать @Transactional в моем весеннем загрузочном приложении (v2.2.5.RELEASE) в Java 8.

В настоящее время я запускаю тестовый сценарий, в котором недопустимый параметр передается как contactEntryType ». При этом никаких изменений в базе данных не должно произойти, но «ContactInformation» для «Contactable» («Person») создается и сохраняется (без отката).

Я уже добавил @EnableTransactionManagement в аннотированную @Configuration class, а также 'spring.jpa.open-in-view = false', как это было рекомендовано в другом месте.

Указанный метод аннотируется с помощью: @Transactional (распространение = Propagation.REQUIRES_NEW, rollbackFor = ResponseStatusException.class Сначала он вызывает getOrCreateContactInformation (...), а затем getOrCreateEntry (...)

private <T extends Contactable> ContactInformation getOrCreateContactInformation(T contactable) {
        if (contactable.getContactInformation() == null) {
            ContactInformation contactInformation = new ContactInformation();
            contactable.setContactInformation(contactInformation);
        }
        return contactable.getContactInformation();
    }

«contactabe» является управляемым объектом.

private ContactEntry getOrCreateEntry(ContactProjection projection) {
        // find existing
        ContactEntry entry = contactEntryRepository.findByContactEntryTypeAndEntry(
                ContactEntryType.get(projection.getEntryType()), projection.getEntry()
        ).orElse(null);
        // create new if needed
        if (entry == null) {
            ContactEntryType type = ContactEntryType.get(projection.getEntryType());
            type.validate(projection.getEntry());
            entry = ContactEntry.builder()
                    .contactEntryType(type)
                    .entry(projection.getEntry())
                    .build();
        }
        return entry;
    }

'ContactEntryType.get ( projection.getEntryType ()) 'генерирует исключение ResponseStatusException в тестовом сценарии, как и должно (я проверял его)

Этот тест выглядит следующим образом.

@Test
    @WithMockUser(authorities = {"c_person", "l_person", "c_cont"})
    public void createContact_violation_unknownType() throws Exception {
        int id = createPersonDataSet().get(0).getId();

        ContactProjection.Imp contact = ContactProjection.Imp.builder()
                .type("test type")
                .entryType("unknown")
                .entry("hydrofin@gmail.com")
                .build();

        assertTrue(contactInformationRepository.findAll().isEmpty());

        mockMvc.perform(
                post(linkTo(CONTROLLER.createContact(id, null)).toUri())
                        .contentType(APPLICATION_JSON_UTF8)
                        .content(asJson(contact))
        ).andExpect(status().isUnprocessableEntity());

        assertTrue(contactRepository.findAll().isEmpty());
        assertTrue(contactEntryRepository.findAll().isEmpty());

        assertTrue(contactInformationRepository.findAll().isEmpty(), "No ContactInformation got created"); // <--- FAILS
        assertNull(personRepository.getOne(id).getContactInformation());
    }

Метод на контроллере вызывает @ Транзакционный аннотированный метод из другого класса, и все методы в этой цепочке, кроме показанных приватных ниже аннотации, публикуются * 1 036 *.

Класс теста помечен @Transactional и использует junit5

Мои свойства теста

spring.jpa.database = H2
spring.jpa.show-sql=true
spring.jpa.open-in-view = false
logging.level.org.springframework.transaction.interceptor = TRACE

Тест выводит следующее (это часть этого):

Began transaction (1) for test context [DefaultTestContext@598bd2ba testClass = PersonControllerMvcTest,
...
Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll]
Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
Completing transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.findById]
Getting transaction for [xxx.services.ContactService.save]
Completing transaction for [xxx.services.ContactService.save] after exception: org.springframework.web.server.ResponseStatusException: 422 UNPROCESSABLE_ENTITY "Unable to find ContactEntryType 'unknown'"
Applying rules to determine whether transaction should rollback on org.springframework.web.server.ResponseStatusException: 422 UNPROCESSABLE_ENTITY "Unable to find ContactEntryType 'unknown'"
Winning rollback rule is: RollbackRuleAttribute with pattern [org.springframework.web.server.ResponseStatusException]
...

Тем не менее после этого hibernate создает сущности.

Я благодарен за любую помощь, спасибо.

РЕДАКТИРОВАТЬ:

Кажется, проблема связана с аннотацией @Transactional, но как я могу получить эффект @Transactional в тесте, не влияя на реальный код службы и контроллера?

...