Невозможно сгенерировать исключение нарушения ограничения при тестировании ограничений Hibernate @Check - PullRequest
0 голосов
/ 10 ноября 2018

Я играю с аннотацией Hibernate @Check, но не может пройти мой тест, если ограничения не выполнены . В настоящее время используется только стандартная конфигурация загрузки Spring с базой данных H2.

Чего мне не хватает? Должен ли быть какой-то флеш после save(..)?

При запуске теста я вижу таблицу, созданную правильно. Если я скопирую строку создания из журнала и использую ее для создания таблицы в моей «реальной» базе данных Postgres, я смогу протестировать различные вставки и убедиться, что эта строка соответствует ограничениям.

Entity

@Getter @Setter
@Entity @Check(constraints = "a IS NOT NULL OR b IS NOT NULL")
public class Constrained {

    @Id @GeneratedValue
    private Long id;

    private String a, b;
}

Тест

@DataJpaTest
@RunWith(SpringRunner.class)
public class HibernateCheckTest {

    @Resource // this repo is just some boiler plate code but attached at 
              // the bottom of question
    private ConstrainedRepository repo;

    @Test @Transactional // also tried without @Transactional
    public void test() {
        Constrained c = new Constrained();
        repo.save(c); // Am I wrong to expect some constraint exception here?
    }
}

Скрипт генерации таблицы при выполнении теста

создать таблицу с ограничениями (id bigint not null, varchar (255), b varchar (255), первичный ключ (id), проверка (a НЕ НУЛЬ ИЛИ b НЕ НЕТ NULL))

Репозиторий (не так много, чтобы увидеть в репо, а просто показать):

public interface ConstrainedRepository
            extends CrudRepository<Constrained, Long> {
}

ОДНАКО

Если я использую EntityManager, добавьте в свой тестовый класс:

@PersistenceContext
private EntityManager em;

и делать так:

em.persist(c);
em.flush();

вместо repo.save(c) я получу исключение.

И

изучая журнал из исходного теста с repo.save(c) более осторожно показывает:

org.springframework.test.context.transaction.TransactionContext: 139 - Откат транзакции для теста:
...
testException = [null],

, поэтому по какой-то причине эта ошибка просто упакована и зарегистрирована. Как его «развернуть» и выбросить при использовании хранилища для сохранения?

Ответы [ 2 ]

0 голосов
/ 10 ноября 2018

Благодаря ответу из codemonkey Мне удалось найти решение.Это решается добавлением:

@org.springframework.transaction.annotation.Transactional(propagation = 
                                                     Propagation.NOT_SUPPORTED)

в мой тестовый класс.

0 голосов
/ 10 ноября 2018

В ConstrainedRepository, расширьте JpaRepository вместо CrudRepository, затем используйте:

repo.saveAndFlush(c);

вместо:

repo.save(c);

Проверка применяется в базе данных, и это происходит только тогда, когда изменения (в этом случае оператор INSERT) сбрасываются в базу данных.

Без явного сброса Hibernate отложит отправку операторов в базу данных, пока транзакция не будет зафиксирована или не будет выполнен запрос.

Однако из Spring DataJpaTest документация:

По умолчанию тесты JPA данных являются транзакционными и в конце откатываются каждого теста.

Итак, в этом случае нет коммита. Откат транзакции и операторы никогда не сбрасываются в базу данных, поэтому исключение не выдается.

...