英文:
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("something").build();
Map<String, Object> mapFromPojo = new ObjectMapper().convertValue(pojo, Map.class);
// this throws an exception
namedParameterJdbcTemplate.update(
"INSERT INTO pojo_table ( id, data ) VALUES ( :id, :data )",
mapFromPojo
);
// this works
namedParameterJdbcTemplate.update(
"INSERT INTO pojo_table ( id, data ) VALUES ( :id, :data )",
ImmutableMap.of("id", pojo.getId(), "data", 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("something").build();
// 当在非TEXT字段上使用PostgreSQL Cast时,映射可以全部是字符串
namedParameterJdbcTemplate.update(
"INSERT INTO pojo_table ( id, data ) VALUES ( :id::uuid, :data )",
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 String
s.
With the POJOObject
from above:
var pojo = POJOObject.builder().data("something").build();
// map can be all strings, when using postgreSQL cast on non-TEXT fields
namedParameterJdbcTemplate.update(
"INSERT INTO pojo_table ( id, data ) VALUES ( :id::uuid, :data )",
new ObjectMapper().convertValue(pojo, Map.class)
);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论