This works on SQL server:
@Type(type = "json")
@Column(columnDefinition = "NVARCHAR(MAX) NULL CHECK(ISJSON(tags) = 1)")
private List<String> tags = Lists.newArrayList();
But you need to do this on H2:
@Type(type = "json")
@Column(columnDefinition = "json")
private List<String> tags = Lists.newArrayList();
Is there a way to use a spring application property:
#h2
json_coldef=json
#sql server
json_coldef=NVARCHAR(MAX) NULL CHECK(ISJSON(tags) = 1)
so that I can do this?
@Type(type = "json")
@Column(columnDefinition = "${json_coldef}")
private List<String> tags = Lists.newArrayList();
so that it loads it from a spring property specified at JVM system property?
In other words, is there some way I can use spring variables inside the JPA annotation values and get variable substitution?
CodePudding user response:
Answer from comments: No. JPA annotations cannot use spring substitutions.
So you will need to find a way to make sure your annotations are completely dialect independent.
So I went ahead and created this work-around to the issue for now. I will just build my own converter:
/** This is a database independent way to convert pojo to json to database, then back to
* pojo from database. There is a better way to do this with {@link com.vladmihalcea.hibernate.type.json.JsonType}, but
* unfortunately it doesn't work in H2.
*/
@javax.persistence.Converter
public static class ListStringConverter implements AttributeConverter<List<String>, String> {
@Override
public String convertToDatabaseColumn(List<String> myCustomObject) {
try {
return objectMapper.writeValueAsString(myCustomObject);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
@Override
public List<String> convertToEntityAttribute(String databaseDataAsJSONString) {
try {
return objectMapper.readValue(databaseDataAsJSONString, List.class);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
Then use it:
@Lob
@Convert(converter = ListStringConverter.class)
private List<String> tags = Lists.newArrayList();
It actually performs pretty much the same too. No performance impact that I can tell.
I will remove H2 and replace with testcontainers to make this all moot point.