mar*_*ers 14 postgresql json jpa jdbc eclipselink
特别是我对使用PostgreSQLs json
类型感兴趣.
问题的核心似乎是Eclipselink中没有内部映射来json
键入.因此,使用一种天真的方法:
@Column(name = "json", columnDefinition = "json")
public String getJson() {
return json;
}
Run Code Online (Sandbox Code Playgroud)
...并尝试插入一个对象,我得到一个例外:
Internal Exception: org.postgresql.util.PSQLException: ERROR: column "json" is of type json but expression is of type character varying
Run Code Online (Sandbox Code Playgroud)
我觉得很公平.
通过EclipseLink文档,似乎适用的自定义(转换映射,本机查询,转换器)依赖于由支持的映射(数字,日期,字符串等)组成的数据,因此使得使用它变得非常尴尬供应商特定类型.
这是如此令人沮丧的主要原因是json
posgresql 中的类型表达与text/varchar相同,我相信(目前,但不是永远)只是该类型的别名 - 因此驱动程序能够传输这个,这只是我的验证规则.
就解决方案而言,我不介意丢失可移植性(在数据库不可知和使用供应商特定类型方面),但只是想要一个允许我json
在普通JPA实体上使用类型作为属性并保留所有它习惯的其他行为(模式生成,合并,持久化,事务代码
Sas*_*812 26
通过SO我已经发现很多关于JSON或XML类型的问题,用于映射到Postgres.看起来没有人面临从自定义Postgres类型读取的问题,因此这里使用纯JPA类型转换机制进行读写解决方案.
Postgres JDBC驱动程序将未知(到Java)类型的所有属性映射到org.postgresql.util.PGobject对象,因此它足以为此类型生成转换器.这是实体示例:
@Entity
public class Course extends AbstractEntity {
@Column(name = "course_mapped", columnDefinition = "json")
@Convert(converter = CourseMappedConverter.class)
private CourseMapped courseMapped; // have no idea why would you use String json instead of the object to map
// getters and setters
}
Run Code Online (Sandbox Code Playgroud)
转换器示例如下:
@Converter
public class CourseMappedConverter implements AttributeConverter<CourseMapped, PGobject> {
@Override
public PGobject convertToDatabaseColumn(CourseMapped courseMapped) {
try {
PGobject po = new PGobject();
// here we tell Postgres to use JSON as type to treat our json
po.setType("json");
// this is Jackson already added as dependency to project, it could be any JSON marshaller
po.setValue((new ObjectMapper()).writeValueAsString(courseMapped));
return po;
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
@Override
public CourseMapped convertToEntityAttribute(PGobject po) {
try {
return (new ObjectMapper()).readValue(po.getValue(),CourseMapped.class);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你真的需要坚持你的实体中的String JSON表示,你可以为String类型制作这样的转换器
implements AttributeConverter<String, PGobject>
Run Code Online (Sandbox Code Playgroud)
这是非常脏(虽然工作)的概念证明,它也使用虚假对象序列化告诉JPA如果它是对象被更改
https://github.com/sasa7812/psql-cache-evict-POC
归档时间: |
|
查看次数: |
6448 次 |
最近记录: |