使用用户定义的主键值保存实体
Saving entities with user defined primary key values
我对 Spring 数据 JDBC 库还很陌生,但到目前为止给我留下了深刻的印象。
不幸的是,我的数据库 (SAP Hana) 的 JDBC 驱动程序不支持在 INSERT 之后检索生成的密钥(方法 PreparedStatement.getGeneratedKeys()
的实现抛出 UnsupportedOperationException
)。
因此我决定不使用生成的密钥,而是在保存之前定义 PK 值(+ 实现 Persistable.isNew()
)。但是,即使在保存之前定义了 PK 值,每当触发 INSERT 操作时,它都会因错误而失败,即无法检索生成的密钥。
在调查了受影响方法 (DefaultDataAccessStrategy.insert
) 的源代码后,我发现,每次执行 JDBC 操作 update
方法时都会使用 KeyHolder
参数。
我(天真地)通过以下更改调整了代码,它开始工作了:
- 如果 PK 已经定义,则调用 JDBC 操作
update
方法而不 KeyHolder
- 然后立即从方法返回这样的 PK
调整后的 insert
方法中的以下代码片段说明了更改。
Object idValue = getIdValueOrNull(instance, persistentEntity);
if (idValue != null) {
RelationalPersistentProperty idProperty = persistentEntity.getRequiredIdProperty();
addConvertedPropertyValue(parameterSource, idProperty, idValue, idProperty.getColumnName());
/* --- tweak start --- */
String insertSql = sqlGenerator.getInsert(new HashSet<>(parameterSource.getIdentifiers()));
operations.update(insertSql, parameterSource);
return idValue;
/* --- tweak end --- */
}
所以,问题是,是否可以在 Spring 数据 JDBC 中实施类似的更改以支持像我这样的用例。
问题可以被视为已关闭,因为相关功能请求已在问题跟踪器中注册。
我对 Spring 数据 JDBC 库还很陌生,但到目前为止给我留下了深刻的印象。
不幸的是,我的数据库 (SAP Hana) 的 JDBC 驱动程序不支持在 INSERT 之后检索生成的密钥(方法 PreparedStatement.getGeneratedKeys()
的实现抛出 UnsupportedOperationException
)。
因此我决定不使用生成的密钥,而是在保存之前定义 PK 值(+ 实现 Persistable.isNew()
)。但是,即使在保存之前定义了 PK 值,每当触发 INSERT 操作时,它都会因错误而失败,即无法检索生成的密钥。
在调查了受影响方法 (DefaultDataAccessStrategy.insert
) 的源代码后,我发现,每次执行 JDBC 操作 update
方法时都会使用 KeyHolder
参数。
我(天真地)通过以下更改调整了代码,它开始工作了:
- 如果 PK 已经定义,则调用 JDBC 操作
update
方法而不KeyHolder
- 然后立即从方法返回这样的 PK
调整后的 insert
方法中的以下代码片段说明了更改。
Object idValue = getIdValueOrNull(instance, persistentEntity);
if (idValue != null) {
RelationalPersistentProperty idProperty = persistentEntity.getRequiredIdProperty();
addConvertedPropertyValue(parameterSource, idProperty, idValue, idProperty.getColumnName());
/* --- tweak start --- */
String insertSql = sqlGenerator.getInsert(new HashSet<>(parameterSource.getIdentifiers()));
operations.update(insertSql, parameterSource);
return idValue;
/* --- tweak end --- */
}
所以,问题是,是否可以在 Spring 数据 JDBC 中实施类似的更改以支持像我这样的用例。
问题可以被视为已关闭,因为相关功能请求已在问题跟踪器中注册。