[英]Java Jpa Custom entity attribute converter and Specification
In my Java code, I have a JPA entity define as below在我的 Java 代码中,我有一个 JPA 实体定义如下
public class Entity {
@Id
private Long id;
... other attributes;
@Column(name = "ctx")
@Convert(converter = MapToJsonStringConverter.class)
private Map<String, String> ctx;
}
@Convert
public class MapToJsonStringConverter implements AttributeConverter<Map<String, String>, String> {
@Autowired
private JsonParserService jsonParserService;
@Override
public String convertToDatabaseColumn(final Map<String, String> map) {
return Optional.ofNullable(map)
.map(jsonParserService::writeValueAsString)
.orElse(null);
}
@Override
public Map<String, String> convertToEntityAttribute(final String string) {
return Optional.ofNullable(string)
.map(jsonParserService::readValueAsMap)
.orElse(null);
}
}
A Jpa attribute converter is used to convert the ctx
attribute to/ from a JSON string. Jpa 属性转换器用于将
ctx
属性与 JSON 字符串相互转换。 I need to create a JPA specification that allows me to query the ctx
field in the database using a LIKE
clause:我需要创建一个 JPA 规范,允许我使用
LIKE
子句查询数据库中的ctx
字段:
ctx LIKE '%test-value%'
Of course, when I try to create such specification the criteria builder cannot match the type of the attribute as it is expecting a map when instead I only supply a string当然,当我尝试创建这样的规范时,标准构建器无法匹配属性的类型,因为它期望 map 而我只提供一个字符串
cb.like(root.get(Entity_.ctx), string)) <--- compile error Cannot resolve method 'like(javax.persistence.criteria.Expression<M>, java.lang.String)'
Is there a way to make this work instead of using a native query?有没有办法使这项工作而不是使用本机查询? Consider that the final specification also involves other attributes of the same entity.
考虑到最终规范还涉及同一实体的其他属性。
As mentionned in commentaries正如评论中提到的
cb.like(root.<String>get("ctx"), clause);
Does not work as root.get(Entity_.ctx)
or its equivalent does return a Map<String, String>
and explicitly typing the generic ( <String>get(...)
) won't help as Map
is not instanceof
String
.不能作为
root.get(Entity_.ctx)
或它的等价物返回一个Map<String, String>
并且显式输入泛型( <String>get(...)
)将无济于事,因为Map
不是instanceof
String
. The solution as mentionned here is to use as
provided by Criteria. 这里提到的解决方案是
as
Criteria 提供的方式使用。
cb.like(root.get(Entity_.ctx).as(String.class), string)
It does work thanks to Map
overriding Object.toString()
.由于
Map
覆盖Object.toString()
,它确实有效。 Otherwise you would need to create your own class extending Map
and custom the override to toString()
to return your custom representation (which is used by default by Json libs).否则,您需要创建自己的 class 扩展
Map
并将覆盖自定义为toString()
以返回您的自定义表示(默认情况下由 Json 库使用)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.