【问题标题】:How to insert null value to foreign key with JDBCTemplate如何使用 JDBCTemplate 将空值插入外键
【发布时间】:2019-03-20 02:06:21
【问题描述】:

我有以下架构:

CREATE TABLE API
(
ID BIGINT NOT NULL,
NAME VARCHAR NOT NULL,
API_PARENT_ID BIGINT,
CONSTRAINT API_PKEY PRIMARY KEY (ID)
CONSTRAINT API_PARENT_ID_FKEY FOREIGN KEY (API_PARENT_ID) references API,
);

我的 API 实体本身有一个 FK,以防 api 依赖(如子父关系)

我已经使用 jdbc 模板处理了自己(意味着我已经避免使用休眠)CRUD 部分。 当我的 API 是父级并且 api_parent_id 值应该为空时,我遇到了问题。

以下行(我已跳过无意义的列):

String _SQL_UPDATE_API = "update api set api_parent_id = ? where id = ?"
this.jdbcTemplate.update(_SQL_UPDATE_API, api.getParent !=null ? api.getParent().getId() : null , api.getId());

返回以下错误:

[90012-196]; nested exception is org.h2.jdbc.JdbcSQLException: Parameter "#1" is not set; SQL statement: update api set api_parent_id = ? where id = ?

我应该如何处理空值? 我已经尝试使用 MapSqlParameterSource 或 PreparedStatement 来指定

ps.setNull(1,Types.NULL); 

【问题讨论】:

    标签: java sql jdbc h2 jdbctemplate


    【解决方案1】:

    ps.setNull(1,Types.NULL);

    很遗憾,您需要根据您的 JDBC 驱动程序设置与列类型相对应的列的特定 JDBC 类型。

    一些 JDBC 驱动程序比其他驱动程序更挑剔。我猜H2需要特定的类型。

    在这种情况下,使用Types.BIGINT,如:

    ps.setNull(1,Types.BIGINT);
    

    【讨论】:

    • 我已经尝试过这个解决方案,但是 H2 将 set null 转换为 0 值,这与我的表中的某些内容不对应,因为它是一个 FK
    • 好吧,终于成功了,我对实体的提取数据有问题,默认情况下它在我的实体上映射了一个新的 ApiParent,然后我的更新它总是不为空并发送0..
    【解决方案2】:

    使用此update 函数将参数与参数类型一起传递。

    Integer id = 1
    Integer parent_id = null
    
    String _SQL_UPDATE_API = "update api set api_parent_id = ? where id = ?";
    
    java.lang.Object[] args = [parent_id, id]
    int[] argTypes   = [java.sql.Types.BIGINT, java.sql.Types.BIGINT]
    
    updCnt = jdbcTemplate.update(_SQL_UPDATE_API, args, argTypes);
    

    注意 - 这是 Groovy 语法,因此如果需要,请针对 Java 进行调整。

    在 Oracle 12 中为我工作。

    【讨论】:

    • 我也试过这个解决方案,但现在我有这个错误:org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [更新 api 设置 api_parent_id = ?其中 id = ?];数据转换错误转换“(-5, -5)”
    • 好吧,如果一切都失败了,我会为 NULLcase 使用 additional 语句:update api set api_parent_id = NULL where id = ?
    • 好吧,这个解决方案行不通,因为 parent_id 不会总是为空
    • 您将使用 if (parent_id != null) then 您的原始声明,并且仅在 else 这个修改后的声明中使用。
    猜你喜欢
    • 2017-01-08
    • 1970-01-01
    • 2019-07-21
    • 2015-09-08
    • 1970-01-01
    • 2019-05-10
    • 2016-05-20
    • 1970-01-01
    • 2014-03-26
    相关资源
    最近更新 更多