【问题标题】:How do I use a UUID in a JDBC template?如何在 JDBC 模板中使用 UUID?
【发布时间】:2017-10-31 13:02:55
【问题描述】:

我正在使用带有 JDBC 模板的 spring 框架,并且我也在使用 postgres。

我在 postgres 中有使用 UUID 作为主键的表,该列的类型是 postgres 的native UUIDs。如何将这些 UUID 存储在通过 JDBC 模板创建的准备好的语句中?

我尝试将 UUID 转换为这样的字符串:

int rowsAffected = this.jdbc.update(sql, new Object[] {
    baseMaterial.getId().toString().toLowerCase(),
    baseMaterial.getName(),
    baseMaterial.getDescription()
});

但这会导致这个错误:

ERROR: column "id" is of type uuid but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.

如果我像这样使用原始 UUID:

int rowsAffected = this.jdbc.update(sql, new Object[] {
    baseMaterial.getId(),
    baseMaterial.getName(),
    baseMaterial.getDescription()
});

然后我会遇到这个错误:

org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of java.util.UUID. Use setObject() with an explicit Types value to specify the type to use.

有什么想法吗?这让我发疯了。

【问题讨论】:

  • 您使用的是哪个版本的 PostgreSQL JDBC 驱动程序?
  • @MarkRotteveel <version>9.1-901-1.jdbc4</version>
  • 我建议你更新到 42.1.4 看看是否能解决你的问题,9.1-901 已经 6 岁了。
  • @MarkRotteveel 果然,解决了它。将其发布为答案,我会接受它

标签: java spring postgresql jdbc jdbctemplate


【解决方案1】:

您使用的 PostgreSQL 驱动程序版本已有 6 年历史,此后进行了很多更改/改进。我建议升级到 42.1.4 版本。

我已经扫描了release notes,但我没有找到他们添加(或改进)对 UUID 支持的具体版本。

【讨论】:

    【解决方案2】:

    尝试像这样在查询中使用类型:

    int[] types = {Types.VARCHAR, Types.VARCHAR, Types.VARCHAR};
    
    int rowsAffected = this.jdbc.update(sql, new Object[]{
        baseMaterial.getId().toString().toLowerCase(),
        baseMaterial.getName(),
        baseMaterial.getDescription()
    }, types);//<<-----------specify the type of each attribute 
    

    【讨论】:

      【解决方案3】:

      您可以尝试使用 Prepared Statement 并让 DB 使用函数 uuid_generate_v1() 处理 uuid 创建

      要使用此功能,您首先需要通过在 Postgres DB 中运行来创建一个扩展:

      CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
      

      然后在你的 DAO 中你可以例如:

      private String ADD_USER = "insert into Users(id, name, description) values (uuid_generate_v1(), ?, ?)";
          
      jdbcTemplate.update(ADD_USER, new PreparedStatementSetter() {
          @Override
          public void setValues(PreparedStatement preparedStatement) throws SQLException {
              preparedStatement.setString(1, name);
              preparedStatement.setString(2, description);
          }
      });
      

      您无需担心插入 uuid,因为数据库会使用函数 uuid_generate_v1(); 为您完成此操作;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多