Я играю с аннотацией Hibernate @Check, но мой тест не может быть провален, если ограничения не выполнены. В настоящее время просто используется конфигурация загрузки Spring по умолчанию с базой данных H2.
Что мне не хватает? Должен ли быть какой-то промывать после save(..)?
При запуске теста я вижу, что таблица создана правильно. Если я скопирую строку создания из журнала и использую ее для создания таблицы в моей «реальной» базе данных Postgres, я могу протестировать различные вставки и увидеть, что с этой строкой все в порядке с ограничениями.
Сущность
@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?
}
}
Скрипт генерации таблицы при запуске теста
create table constrained (id bigint not null, a varchar(255), b varchar(255), primary key (id), check (a IS NOT NULL OR b IS NOT 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 - Rolled back transaction for test:
...
testException = [null],
поэтому по какой-то причине эта ошибка просто переносится и регистрируется. Как его "развернуть" и выбросить при использовании репозитория для сохранения?




В ConstrainedRepository расширите JpaRepository вместо CrudRepository, затем используйте:
repo.saveAndFlush(c);
вместо того:
repo.save(c);
Проверка выполняется в базе данных, и это происходит только тогда, когда изменения (в данном случае оператор INSERT) сбрасываются в базу данных.
Без явного сброса Hibernate отложит отправляет операторы в базу данных до тех пор, пока транзакция не будет зафиксирована или пока не будет выполнен запрос.
Однако из документации Spring DataJpaTest:
By default, data JPA tests are transactional and roll back at the end of each test.
Итак, в этом случае фиксации нет. Транзакция откатывается, и операторы никогда не сбрасываются в базу данных, поэтому исключение никогда не генерируется.
Ах, извините, этот метод находится в JpaRepository, но не в CrudRepository. Обновили мой ответ.
Благодаря отвечать от Codemonkey я смог найти решение. Это разрешается добавлением:
@org.springframework.transaction.annotation.Transactional(propagation =
Propagation.NOT_SUPPORTED)
в мой тестовый класс.
Спасибо. Я бы предположил что-то подобное. Я видел этот метод в некоторых вопросах и ответах, но теперь моя проблема в том, что мои репозитории не содержат этого метода? Сконструировать myt-репо или протестировать как-то иначе? (я тоже просматриваю документы, но если вы знаете быстрый ответ)