java - 使用 JPA 将 JSON 存储到 postgres 中?
问题描述
我正在尝试使用 EclipseLink JPA 实现将 JSON 字符串从我的 AS 持久化到 postgresql 中。
为此,我JsonObject
在 JPA 中使用了 javax 并编写了一个转换器来转换为PGObject
JPA:
import javax.json.JsonObject;
@Entity
@Table(name="\"CONTAINER\"")
@NamedQuery(name="Container.findAll", query="SELECT r FROM Container r")
public class Container implements ResourceJPA, Serializable {
@Column(name="\"creationTime\"")
private Timestamp creationTime;
@Column(name="\"creator\"")
private String creator;
@Convert(converter=JsonConverter.class)
@Column(name="\"customAttribute\"", columnDefinition = "jsonb")
private JsonObject customAttribute;
...
}
json转换器:
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import javax.json.Json;
import javax.json.JsonObject;
import javax.persistence.Converter;
import org.postgresql.util.PGobject;
@Converter(autoApply = true)
public class JsonConverter implements javax.persistence.AttributeConverter<JsonObject, Object> {
private static final long serialVersionUID = 1L;
private static ObjectMapper mapper = new ObjectMapper();
@Override
public Object convertToDatabaseColumn(JsonObject objectValue) {
try {
PGobject out = new PGobject();
out.setType("json");
out.setValue(objectValue.toString());
return out;
} catch (Exception e) {
throw new IllegalArgumentException("Unable to serialize to json field ", e);
}
}
@Override
public JsonObject convertToEntityAttribute(Object dataValue) {
try {
if (dataValue instanceof PGobject && ((PGobject) dataValue).getType().equals("json")) {
return mapper.reader(new TypeReference<JsonObject>() {
}).readValue(((PGobject) dataValue).getValue());
}
return Json.createObjectBuilder().build();
} catch (IOException e) {
throw new IllegalArgumentException("Unable to deserialize to json field ", e);
}
}
}
我收到以下错误java.io.NotSerializableException
:
Caused by: Exception [EclipseLink-67] (Eclipse Persistence Services - 2.4.2.v20130514-5956486): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Could not serialize object into byte array.
Internal Exception: java.io.NotSerializableException: org.glassfish.json.JsonObjectBuilderImpl$JsonObjectImpl
Mapping: org.eclipse.persistence.mappings.DirectToFieldMapping[customAttribute-->CONTAINER.customAttribute]
Descriptor: RelationalDescriptor(...jpa.Container --> [DatabaseTable(CONTAINER)])
at org.eclipse.persistence.exceptions.DescriptorException.notSerializable(DescriptorException.java:1228)
at org.eclipse.persistence.mappings.converters.SerializedObjectConverter.convertObjectValueToDataValue(SerializedObjectConverter.java:89)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.getFieldValue(AbstractDirectMapping.java:746)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.writeFromObjectIntoRow(AbstractDirectMapping.java:1241)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildRow(ObjectBuilder.java:1201)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildRow(ObjectBuilder.java:1189)
at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:436)
at org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:80)
at org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:90)
at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:286)
at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:852)
at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:751)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2879)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1607)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1589)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1540)
at org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:226)
at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:125)
at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:3945)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1423)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:638)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithPreBuiltChangeSet(UnitOfWorkImpl.java:1569)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:445)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:798)
... 255 more
Caused by: java.io.NotSerializableException: org.glassfish.json.JsonObjectBuilderImpl$JsonObjectImpl
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at org.eclipse.persistence.mappings.converters.SerializedObjectConverter.convertObjectValueToDataValue(SerializedObjectConverter.java:86)
... 280 more
jsonb
将 JSON 存储到 postgres字段中是否有更好的选择?
解决方案
推荐阅读
- javascript - 如何在javascript中从下拉列表中显示选定的选项
- python - 值更改时更改颜色组合框
- javascript - 图像作为光标,滚动时应该移动
- reactjs - React useRouteMatch 不显示嵌套链接内容
- here-api - 突然无法加载 HERE 地图。甚至在他们的示例网站上也无法加载
- android - Retrofit 2 Xml Parse“参数'DASH'在类中没有匹配”
- android - FTS4 matchinfo 不适用于 android 房间数据库
- resilience4j - 带有 Spring mvc 的断路器注释(不是 Spring-boot)
- python - 使用 Python 和 xorg-server 监控计算机上花费的时间
- modelica - 试图模拟球和梁问题