Я запускаю SQL Anywhere 16.0 и пытаюсь использовать мои шаблоны Spring JDBC. То, что мне нужно сделать, очень просто: вставьте строку в таблицу, а затем верните автоматически генерируемое значение идентификатора.Функция getGeneratedKeys не поддерживается этой базой данных
public int log() {
SimpleJdbcInsert insertActor =
new SimpleJdbcInsert(ds)
.withTableName("DBA.REQUESTS")
.usingGeneratedKeyColumns("REQUEST_ID");
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("USER_ID", userId);
parameters.put("DATA_TYPE_ID", getProductSku());
parameters.put("PRICE", price);
// ...more parameters
Number requestIdNumber = insertActor.executeAndReturnKey(parameters);
return requestIdNumber.intValue();
}
Но весна неоднократно дает мне ошибку
org.springframework.dao.InvalidDataAccessResourceUsageException:
The getGeneratedKeys feature is not supported by this database
Водитель Я использую должен поддерживать JDBC 4.0 (библиотека dbjdbc16.dll и находится в пути, и sajdbc4.jar в каталог Tomcat lib). Соответствующая информация подключения к базе данных с Tomcat является
<Resource auth="Container" description="Pooled connection to the web database"
driverClassName="sybase.jdbc4.sqlanywhere.IDriver"
maxActive="30" maxIdle="5" maxWait="10000" name="jdbc/web"
removeAbandoned="true"
removeAbandonedTimeout="60"
type="javax.sql.DataSource"
url="jdbc:sqlanywhere:Server=web;UID=xxx;PASSWORD=xxx;port=xxxx;LINKS=tcpip(PORT=xxxx)"/>
и контекст Spring приложения для источника данных является
<jee:jndi-lookup id="dbDataSource" jndi-name="jdbc/web"
expected-type="javax.sql.DataSource" />
Так что мой вопрос, есть ли способ настроить вещи лучше, чтобы этот тип заявления работает? OR Если база данных по-настоящему не поддерживает это на каком-то фундаментальном уровне, есть ли не уродливая альтернатива для меня, чтобы вставлять значения и возвращать сгенерированный идентификатор.
UPDATE: Похоже, что драйвер базы данных не поддерживает эту функцию. Предложения здесь и в другом месте должны были сделать INSERT, чем SELECT сразу после. Проблема, конечно, в том, что если другой пользователь вставит в таблицу между этими двумя утверждениями, вы получите неправильное значение, и в этом случае это будет очень плохо.
Моим обходным решением сейчас является использование блокировки на уровне класса в соответствующем DAO и выбор по нескольким столбцам (не только IDENTITY), так что я могу быть 99.9% уверен, что получаю ту же строку назад. Достаточно хорошо работать. Тем не менее, я бы предпочел иметь транзакционный способ блокировки таблицы. Я не думаю обозначение функции @Transactional будет работать для этого, правильно, так как это просто задерживает фиксацию до тех пор, пока все утверждения не будут успешными?
Помогает ли [этот вопрос] (http://stackoverflow.com/q/16932814/2144390)? –
Нет, к сожалению, это именно то, что я сделал. –
Поддерживает ли драйвер поддержку возврата сгенерированного ключа? Это дополнительная функция в спецификации JDBC 4.0. Вы можете определить, работает оно или нет, проверяя метаданные базы данных JDBC с помощью метода «DatabaseMetaData.supportsGetGeneratedKeys». –