如何将基元的ArrayList映射到单个列?

Ari*_*său 8 many-to-many hibernate one-to-many

假设我有以下情况:

Object Car有一个ArrayList的价格,这些都是数字.是否可以在Hibernate中将所有价格保存在一列中?我知道这违反了第一个普通形式,但可能存在这样的情况,即您不希望将它们保存在单独的表中,就像它在一对多或多对多关系中经典地完成一样.

在JDO中,我可以通过将ArrayList保存在BLOB列中来轻松完成此操作.

一些有用的相关SOF的问题:原始类型在Hibernate中的ArrayList中地图的ArrayList与Hibernate.

任何想法都将受到高度赞赏!

小智 21

我知道这是一个老问题,但对于任何想在JPA环境中执行此操作的人,您都可以这样做

import org.apache.commons.lang3.StringUtils;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.Collections;

@Converter
public class IntArrayToStringConverter implements AttributeConverter<List<Integer>,String>{
    @Override
    public String convertToDatabaseColumn(List<Integer> attribute) {
        return attribute == null ? null : StringUtils.join(attribute,",");
    }

    @Override
    public List<Integer> convertToEntityAttribute(String dbData) {
        if (StringUtils.isBlank(dbData))
            return Collections.emptyList();

        try (Stream<String> stream = Arrays.stream(dbData.split(","))) {
            return stream.map(Integer::parseInt).collect(Collectors.toList());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在你的实体中使用它

@Entity
public class SomeEntity
{

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Integer id;

   @Column
   @Convert(converter = IntArrayToStringConverter.class)
   private List<Integer> integers;

   ...
}
Run Code Online (Sandbox Code Playgroud)

请享用 !!!

  • 不错的解决方案,但请注意,这仅从 JPA 2.1 开始可用。 (2认同)

JB *_*zet 7

AFAIR,Hibernate将使用本机序列化并将结果字节存储在列中.我不会这样做,并使用专门的转换,使价格在数据库中可读,并且至少能够使用数据而无需Java本机序列化:

@Basic
private String prices;

public void setPrices(List<Integer> prices) {
    this.prices = Joiner.on(',').join(prices);
}

public List<Integer> getPrices() {
    List<Integer> result = new ArrayList<Integer>();
    for (String s : Splitter.on(',').split(this.prices)) {
        result.add(Integer.valueOf(s));
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)