Java JPA:将值列表保存为逗号分隔的值

Java JPA:将值列表保存为逗号分隔的值,java,hibernate,jpa,Java,Hibernate,Jpa,我收到一个简单的值列表,这是JSON请求的一部分,我想将其保存为逗号分隔的值。尝试使用以下命令,但无效 @Column(nullable = true) @GeneratedValue(strategy = GenerationType.AUTO) private ArrayList<String> services = new ArrayList<String>() ; @列(nullable=true) @GeneratedValue(策略=GenerationTy

我收到一个简单的值列表,这是JSON请求的一部分,我想将其保存为逗号分隔的值。尝试使用以下命令,但无效

@Column(nullable = true)
@GeneratedValue(strategy = GenerationType.AUTO)
private ArrayList<String> services = new ArrayList<String>() ;
@列(nullable=true)
@GeneratedValue(策略=GenerationType.AUTO)
私有ArrayList服务=新建ArrayList();

@列(nullable=true)
@ElementCollection(targetClass=String.class)
private List services=new ArrayList();

@ElementCollection
引发异常,表示
表服务不存在

该@ElementCollection需要一个表来存储多行值

所以您可以定义为字符串列,并在getter和setter中连接/分解,如下所示

private String services;

public setServices(String services[]) //Can be Array or List
{
     // this.services = Iterate services[] and create a comma separated string or Use ArrayUtils
}

public String[] getServices() //Can be Array or List
{
    // services.split(",") to get a list of Strings, then typecast/parse them to Strings before returning or use Arrays.asList(arguments.split(","));
}

正如其他人在评论中提到的,
AttributeConverter
工作得非常好。这一个使用Jackson序列化为JSON数组。我建议使用JSON,因为它可以干净地处理分隔符转义、空值、引号等:

@Converter
public class StringListAttributeConverter implements AttributeConverter<List<String>, String> {

    private static final TypeReference<List<String>> TypeRef = new TypeReference<List<String>>(){};

    @Override
    public String convertToDatabaseColumn (List<String> attribute) {
        if (attribute == null) {
            return null;
        }
        try {
            return ObjectMapperFactory.getInstance().writeValueAsString(attribute);
        }
        catch (IOException ex) {
            throw new UncheckedIOException(ex);
        }
    }

    @Override
    public List<String> convertToEntityAttribute (String dbData) {
        if (dbData == null) {
            return null;
        }
        try {
            return ObjectMapperFactory.getInstance().readValue(dbData, TypeRef);
        }
        catch (IOException ex) {
            throw new UncheckedIOException(ex);
        }
    }
}
@转换器
公共类StringListAttributeConverter实现AttributeConverter{
私有静态最终TypeReference TypeRef=新的TypeReference(){};
@凌驾
公共字符串convertToDatabaseColumn(列表属性){
if(属性==null){
返回null;
}
试一试{
返回ObjectMapperFactory.getInstance().writeValueAsString(属性);
}
捕获(IOEX异常){
抛出新的未选中异常(ex);
}
}
@凌驾
公共列表convertToEntityAttribute(字符串dbData){
if(dbData==null){
返回null;
}
试一试{
返回ObjectMapperFactory.getInstance().readValue(dbData,TypeRef);
}
捕获(IOEX异常){
抛出新的未选中异常(ex);
}
}
}

我使用过这个类,它在大多数情况下都很有效。我发现的一个警告是,使用此转换器可能会混淆一些JPA条件查询,因为它需要实体上的类型列表,但在db中找到一个字符串。

ElementCollection仍然将集合存储在单独的表中,每行一个字符串。我不知道您在哪里读到它将元素存储为逗号分隔的值。您需要一个自定义类型,或者一个JPA属性。此外,用GeneratedValue注释字符串列表没有任何意义。您可以尝试使用AttributeConverter作为替代方法:也可以将值存储到临时列表中,并且仅在向DB写入/读取时将其转换为字符串值或从字符串值转换。请参阅-这将提高biť的性能,因为当您向实体读/写值时,转换并不总是发生。或者你也可以使用@Ish的建议
@Converter
public class StringListAttributeConverter implements AttributeConverter<List<String>, String> {

    private static final TypeReference<List<String>> TypeRef = new TypeReference<List<String>>(){};

    @Override
    public String convertToDatabaseColumn (List<String> attribute) {
        if (attribute == null) {
            return null;
        }
        try {
            return ObjectMapperFactory.getInstance().writeValueAsString(attribute);
        }
        catch (IOException ex) {
            throw new UncheckedIOException(ex);
        }
    }

    @Override
    public List<String> convertToEntityAttribute (String dbData) {
        if (dbData == null) {
            return null;
        }
        try {
            return ObjectMapperFactory.getInstance().readValue(dbData, TypeRef);
        }
        catch (IOException ex) {
            throw new UncheckedIOException(ex);
        }
    }
}