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
?
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)
);