gpt4 book ai didi

postgresql - eclipselink + @convert(json) + postgres + 列表属性

转载 作者:行者123 更新时间:2023-11-29 11:34:19 27 4
gpt4 key购买 nike

我正在使用 eclipselink 2.6 作为 spring data jpa 的持久性提供者,据我所知,它现在允许您使用内部 moxy 序列化程序将实体的子树序列化为 json。

所以我尝试将其混合使用 postgres 的 json 数据类型从嵌入式元素集合迁移到序列化的 json。我有一个名为 Product 的实体,该实体具有以下映射属性:

@Convert(Convert.JSON) 
private List<MetadataIndex> indexes=new ArrayList<MetadataIndex> ();

其中元数据索引是一个具有一些字符串属性的简单类。我想将此对象列表转换为 json 并将其存储到 postgres 中的 json 数据类型的列中。

我认为上面的代码应该足够了,但事实并非如此。应用程序在启动时崩溃(无法创建 entitymanager 工厂 - npe somwhere inside eclipselink)。

如果我将转换器更改为 @Convert(Convert.SERIALIZED) 它会起作用。它在名为 indexes 的表 Products 上创建一个名为 indexes 的字段,并将序列化列表存储在其中。这是 eclipselink 错误还是我遗漏了什么?

谢谢。

最佳答案

好吧,我使用自定义的 eclipselink 转换器将我的类转换为 json 对象,然后直接使用 postgres 驱动程序将它们存储到数据库中。这是转换器。

import fr.gael.dhus.database.jpa.domain.MetadataIndex;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.sessions.Session;
import org.postgresql.util.PGobject;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

/**
* Created by fmarino on 20/03/2015.
*/
@Converter
public class JsonConverter implements org.eclipse.persistence.mappings.converters.Converter {

private static ObjectMapper mapper = new ObjectMapper();

@Override
public Object convertObjectValueToDataValue(Object objectValue, Session session) {
try {
PGobject out = new PGobject();
out.setType("jsonb");
out.setValue( mapper.writerWithType( new TypeReference<Collection<MetadataIndex>>() {} )
.writeValueAsString(objectValue) );
return out;
} catch (IOException e) {
throw new IllegalArgumentException("Unable to serialize to json field ", e);
} catch (SQLException e) {
throw new IllegalArgumentException("Unable to serialize to json field ", e);
}
}

@Override
public Object convertDataValueToObjectValue(Object dataValue, Session session) {
try {
if(dataValue instanceof PGobject && ((PGobject) dataValue).getType().equals("jsonb"))
return mapper.reader( new TypeReference<Collection<MetadataIndex>>() {}).readValue(((PGobject) dataValue).getValue());
return "-";
} catch (IOException e) {
throw new IllegalArgumentException("Unable to deserialize to json field ", e);
}
}

@Override
public boolean isMutable() {
return false;
}

@Override
public void initialize(DatabaseMapping mapping, Session session) {

}

}

如您所见,我使用 jackson 进行序列化,并将数据类型指定为 Collection。你可以在这里使用你想要的类型。

在我的类(class)中,我用这个映射了我的领域:

@Convert(converter = JsonConverter.class)
@Column (nullable = true, columnDefinition = "jsonb")

还将此注释添加到类中:

@Converter(converterClass = JsonConverter.class, name = "jsonConverter")

为了让 jackson 正常工作,我还在我的 MetadataIndex 类中添加了这个注释,在类元素上:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")

我个人喜欢直接使用 postgres 驱动来存储那些特殊的数据类型。我没有设法通过休眠实现同样的目标。至于转换器,我更喜欢更通用的解决方案,但 jackson 强制我说明我想要转换的对象类型。如果您找到更好的方法,请告诉我。

通过类似的方法,我还设法使用了 postgres 的 hstore 数据类型。

关于postgresql - eclipselink + @convert(json) + postgres + 列表属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29149167/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com