保留使用ObjectMapper::convertValue()时特定字段的原始类型。

huangapple go评论73阅读模式
英文:

Keep original type for certain fields when using ObjectMapper::convertValue()

问题

我想生成一个Map对象,作为参数传递给现有POJO的NamedParameterJdbcTemplate::update()的第二个参数。其中一个属性的类型是java.util.UUID

@Builder
@Data
static class POJOObject {
  @Builder.Default
  @NonNull
  private UUID id = UUID.randomUUID();
  @NonNull
  private String data;
}

当使用对象映射器映射此对象时,给定的属性被序列化为String,导致数据库操作失败。

var pojo = POJOObject.builder().data("something").build();
Map<String, Object> mapFromPojo = new ObjectMapper().convertValue(pojo, Map.class);
// 这会抛出异常
namedParameterJdbcTemplate.update(
    "INSERT INTO pojo_table ( id, data ) VALUES ( :id, :data )",
    mapFromPojo
);
// 这样可以正常工作
namedParameterJdbcTemplate.update(
    "INSERT INTO pojo_table ( id, data ) VALUES ( :id, :data )",
    ImmutableMap.of("id", pojo.getId(), "data", pojo.getData())
);

PostgreSQL表定义如下:

CREATE TABLE pojo_table (
   id   UUID PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(),
   data TEXT NOT NULL
)

有没有办法使用ObjectMapper,使id键的值类型为UUID,而不是被序列化为String?或者是否甚至有另一种/更好的方式将POJOObject实例的数据传递给NamedParameterJdbcTemplate::update()调用,而不必手动逐个添加到Map中?

英文:

I want to generate a Map object to be passed as argument to a NamedParameterJdbcTemplate::update() as second parameter from an existing POJO. One property is of type java.util.UUID.

@Builder
@Data
static class POJOObject {
  @Builder.Default
  @NonNull
  private UUID id = UUID.randomUUID();
  @NonNull
  private String data;
}

When this object is mapped with object mapper the given property is serialized to a String and the database operation fails.

var pojo = POJOObject.builder().data(&quot;something&quot;).build();
Map&lt;String, Object&gt; mapFromPojo = new ObjectMapper().convertValue(pojo, Map.class);
// this throws an exception 
namedParameterJdbcTemplate.update(
    &quot;INSERT INTO pojo_table ( id, data ) VALUES ( :id, :data )&quot;,
    mapFromPojo
);
// this works
namedParameterJdbcTemplate.update(
    &quot;INSERT INTO pojo_table ( id, data ) VALUES ( :id, :data )&quot;,
    ImmutableMap.of(&quot;id&quot;, pojo.getId(), &quot;data&quot;, pojo.getData()
);

The PostgreSQL table is defined as follows:

CREATE TABLE pojo_table (
   id   UUID PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(),
   data TEXT NOT NULL
)

Is there a way to use the ObjectMapper so that the value's type of the id key is UUID instead of being serialized into a String? Or is there even another/better way to pass the data of POJOObject instance to the NamedParameterJdbcTemplate::update() call without manually adding field by field to a Map?

答案1

得分: 0

这就是为什么您目前的更新会失败 - 在传递到查询时,您必须指定它是 UUID 类型。我认为您在这里最好的选择就是手动创建映射 - 这样当您添加值时就不会有任何意外。但是您说得对,那就是问题所在。

英文:

That's why the update fails as you have it - you have to specify when passing to the query that it's a UUID type. I think your best bet here is to just manually create the map - that way you don't have any surprises when you add values. But you're right, that's the issue.

答案2

得分: 0

有一个解决方案,在此之前我完全忽略了:PostgreSQL Cast。为了使其工作,需要修改SQL字符串以进行类型转换,这样映射的所有属性就可以作为String传递。

使用上面的POJOObject

var pojo = POJOObject.builder().data(&quot;something&quot;).build();

// 当在非TEXT字段上使用PostgreSQL Cast时,映射可以全部是字符串
namedParameterJdbcTemplate.update(
    &quot;INSERT INTO pojo_table ( id, data ) VALUES ( :id::uuid, :data )&quot;,
    new ObjectMapper().convertValue(pojo, Map.class)
);
英文:

There is a solution, that I completely oversaw before: PostgreSQL Cast. To make it work, the SQL string needs to be modified to cast types and that way all properties of the map can be passed as Strings.

With the POJOObject from above:

var pojo = POJOObject.builder().data(&quot;something&quot;).build();

// map can be all strings, when using postgreSQL cast on non-TEXT fields  
namedParameterJdbcTemplate.update(
    &quot;INSERT INTO pojo_table ( id, data ) VALUES ( :id::uuid, :data )&quot;,
    new ObjectMapper().convertValue(pojo, Map.class)
);

huangapple
  • 本文由 发表于 2020年7月23日 13:41:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/63047586.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定