Я в некотором роде гость в другой системе в нашем приложении, и я не хочу вносить какие-либо изменения с крупномасштабными разветвлениями.
Я пишу юнит-тест с нуля, так как предыдущий автор не заморачивался. (Ворчание.) Я пытаюсь вставить строку, чтобы проверить свой запрос с помощью JPA / hibernate, и был удивлен, увидев следующую ошибку:
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: integrity constraint violation: NOT NULL check constraint; SYS_CT_14316 table: OPTIONVALUE column: OPTION_INDEX
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1377)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1306)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:989)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:293)
at com.sun.proxy.$Proxy109.flush(Unknown Source)
Особенно, когда я знал, что установил значение, потому что мне нужно было написать для него сеттер. Затем на одном из объектов я нашел следующее определение (которое мне пришлось искать):
public static final String OPTION_VALUE_POSITION_COLUMN = "option_index";
@Column(name = OPTION_VALUE_POSITION_COLUMN, insertable = false, updatable = false, nullable = false)
private int position;
Это объясняет, почему я все еще получаю ноль в этом столбце.
У меня нет ОГРОМНОЙ проблемы с удалением вставляемого элемента, потому что он не создается автоматически, так почему бы вам НЕ включать его, если вы вставляете запись, что, очевидно, никогда не происходит внутри системы. А обновляемый защитит его. Но я действительно не хочу, если мне не нужно.
Итак, мой вопрос: есть ли способ переопределить это только для модульного теста. Я пробовал погуглить пару вещей, но сформулировать это было немного проблематично, и я ничего не нашел.
@daniu С точки зрения. Как проверить запрос без механизма запросов и данных?
Вы этого не сделаете, использовать двигатель - это нормально. Однако, как только вы начинаете манипулировать тестируемым кодом, эти тесты становятся гораздо менее значимыми.
@daniu Вы не ошиблись, но какие у меня варианты?
Вы имеете в виду, как использовать orm.xml?
@BillyFrost Каким образом?
поскольку orm.xml переопределяет то, что определено в аннотациях ...
и вы говорите, что я могу использовать это, например, в тестовых ресурсах или в чем-то подобном?




Обычно вы можете переопределить любой класс в тестовых пакетах, и он будет загружен вместо основного класса, потому что он имеет более высокий приоритет. Пути загрузки классов обычно имеют приоритет в следующем порядке:
Вы можете проверить это так:
// I have yet to run into a custom ClassLoader that does not extend URLClassLoader
URLClassLoader urls = (URLClassLoader) getClass().getClassLoader();
for (URL url : urls.getURLs()) {
System.out.println(url);
}
Однако здесь есть небольшая проблема. ClassLoader Hibernate может (а может и не прочитать) переопределенный класс из Test, если у вас нет файла конфигурации persistence.xml, orm.xml или чего-то еще в тестовых ресурсах. Это может быть, а может и не быть, но если вам нужно иметь отдельную конфигурацию в тесте, тогда должен перечисляет все классы, которые необходимо просканировать. Вы не можете полагаться на запись <exclude-unlisted-classes>false</exclude-unlisted-classes>, потому что сканер Hibernate знает глубину и не проникает в иерархию пути к классу глубже, чем уровень, на котором он нашел конфигурационный XML.
Я не знаю, лучшее ли это решение, но в некоторых случаях это может быть законный обходной путь.
Я использовал необработанные запросы для вставки / обновления своих объектов в следующих случаях:
Query query = entityManager.createNativeQuery("insert into MY_TABLE " +
"(ID, NAME) values (1, 'user1')");
query.executeUpdate();
Значит, вы пишете интеграционный тест, а не модульный тест?