如何在JDBC模板中使用UUID?

时间:2017-10-31 13:02:55

标签: java spring postgresql jdbc jdbctemplate

我正在使用带有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.

有什么想法吗?这让我很生气。

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:1)

尝试在查询中使用类型:

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 

答案 2 :(得分:0)

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

为了使用这个函数,你首先需要通过在你的 Postgres 数据库中运行它来创建一个扩展:

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() 为您执行此操作;