Я помещаю данные в базу данных с simpleJdbcTemplate.
simpleJdbcTemplate.update("insert into TABLE values(default)");
Я не хочу помещать любые данные, потому что мне не нужны они для моей цели модульного теста.
Как я могу получить идентификатор от вставленной строки? Я могу retriev текущее значение последовательности, но если кто-то еще сделает вставку затем, я буду, получают следующее значение последовательности.
Там какой-либо путь состоит в том, чтобы использовать simpleJdbcTemplate, чтобы вставить строку и получить идентификатор? Метод обновления возвращает количество вставленных строк, и я хотел бы иметь идентификатор. Спасибо за Вашу справку.
Вы должны сначала запросить id
из соответствующей последовательности
, а затем предоставить этот id
в своем операторе вставки. Вот так просто.
Далее, мы называем это интеграционным тестированием, а не юнит-тестом. Вы можете обратиться к этому потоку SO, чтобы иметь представление об интеграционных тестах и идентификаторах.
[Edited after comment]
В таком случае, избавьтесь от этого триггера. И получайте id
из sequence
напрямую, до того, как сделать insert
.
Ну, вы можете выполнить SELECT... для UPDATE
таблицы, и взять последний id
, и увеличить его на 1. Если ваш id
не является последовательным, что, я думаю, не так, вы можете держать ROWID
, специфичный для Oracle AFAIK. И затем запросить id
, используя его. Действительно, все это можно обойти.
Примечание: Я настоятельно рекомендую вам посмотреть пост Аарона Дигуллы. Посмотрите, достаточно ли этого.
Вам нужно вручную обработать последовательность, чтобы легко получить id, не привязываясь к конкретному продукту RDBMS.
Это означает, что вы должны определить специфичный для развертывания DataFieldMaxValueIncrementer
bean и внедрить его в свой класс обработки базы данных так же, как вы, скорее всего, делаете это с DataSource
. Определение боба должно выглядеть примерно так (этот пример для PostgreSQL):
<bean id="incrementer" class="org.springframework.jdbc.support.incrementer.PostgreSQLSequenceMaxValueIncrementer">
<property name="dataSource" ref="dataSource" />
<property name="incrementerName" value="seq_name" />
</bean>
Затем, когда у вас есть инкрементатор в вашем классе, вы можете использовать его в коде для получения значения id примерно так:
public long saveBeanAndReturnId(Bean b) {
long id = incrementer.nextLongValue();
simpleJdbc.update("...");
return id;
}
Ответьте на этот вопрос: Чего вы пытаетесь добиться с помощью вашего теста? Проверить, что обновление выполняется без ошибок? Что вы каждый раз получаете новый ID? Что таблица существует?
В зависимости от ответа, вы должны изменить свой тест. Если вы просто хотите убедиться в правильности синтаксиса утверждения, вам не нужно ничего делать, кроме как запустить утверждение (оно выдаст исключение, если произойдет ошибка, из-за которой тест не пройдет).
Если вы хотите убедиться, что каждый раз получаете новый ID, вы должны запросить последовательность два раза и проверить, что второе значение отличается от первого.
Если вы хотите проверить, что вставлена строка с новым уникальным ID, просто запустите вставку и проверьте, что она возвращает 1. Если это сработает, вы будете знать, что первичный ключ (ID) не был нарушен и что ряд был вставлен. Следовательно, механизм "добавить с уникальным ID" должен работать.
[EDIT] Не существует способа протестировать триггер, который добавляет ID к новой строке, потому что Oracle не имеет средств для возврата ID, который он только что создал. Вы можете прочитать последовательность, но нет гарантии, что nextval-1
даст вам тот же результат, который увидел триггер.
Вы можете попробовать select max(ID)
, но это может не сработать, если кто-то другой вставит еще один ряд и зафиксирует его до того, как вы сможете выполнить запрос (используя уровень транзакции по умолчанию READ_COMMITTED
).
Поэтому я настоятельно рекомендую избавиться от триггера и использовать стандартный двухшаговый алгоритм ("получить новый ID" плюс "вставить с новым ID"), который используют все остальные. Это сделает ваши тесты более простыми и менее хрупкими.