【问题标题】:How to serialize a collection property in Hibernate?如何在 Hibernate 中序列化集合属性?
【发布时间】:2011-12-06 21:43:12
【问题描述】:

免责声明:我对 Java 开发完全陌生。我已经做了很多 C# 和一些 NHibernate,但是这个 @Attributes 和 get/set 方法的世界对我来说完全陌生。

问题:我有一个非常简单的持久对象

@Entity
@Table(name = "ADMIN_SETTINGS")
public class AdminSettings extends ClientEntity {
    @Column(name = "SAMPLE_ID_PREFIX")
    private String sampleIdPrefix;
    @Column(name = "USE_24_Hr_CLOCK")
    private Boolean use24hrClock;

    private Integer[] FieldsForSampleBoxView;
 ...

映射我遇到的最后一个字段。它是一个最多包含 3 个整数的简单列表。我不需要一个一对多的表,我不需要聚合它,我只需要将集合序列化到数据库中的一个字段。理想情况下是通过人类可读的东西,但老实说,我不在乎。

我该如何进行映射?

【问题讨论】:

    标签: java hibernate orm mapping


    【解决方案1】:

    如果它最多包含 3 个整数,为什么不将这三个整数存储在三列中呢?这至少会被规范化和可查询。如果不是,那么只需使用一个持久的 String 属性,并在 getter 中解析此字符串并在 setter 中转换为字符串:

    @Column(FIELDS_FOR_SAMPLE_VIEW_BOX)
    private String fieldsForSampleViewBox;
    
    public void setFieldsForSampleViewBox(Integer[] array) {
        StringBuilder b = new StringBuilder();
        for (int i = 0; i < array.length; i++) {
            if (array[i] != null) {
                b.append(array[i]);
            }
            if (i < array.length - 1) {
                b.append(',');
            }
        }
        fieldsForSampleViewBox = b.toString();
    }
    
    public Integer getFieldsForSampleViewBox() {
        if (fieldsForSampleViewBox == null || fieldsForSampleViewBox.length() == 0) {
            return new Integer[0];
        }
        String[] strings = fieldsForSampleViewBox.split(",");
        Integer[] result = new Integer(strings.length());
        for (int i = 0; i < strings.length(); i++) {
            if (!strings[i].equals("") {
                result[i] = Integer.valueOf(strings[i]);
            }
        }
        return result;
    }
    

    您也可以在 Integer 数组上使用 @Lob 注释或 @Type(type="serializable") 注释,但随后将使用本机 Java 序列化,并且它更脆弱且不可读。

    【讨论】:

    • 所以,如果我只是将 @Column("FIELDS_FOR_SAMPLE_VIEW_BOX")@Type(type="serializable") 放在我的 Integer[] 数组上,它应该可以工作吗?老实说,如果这段数据被损坏并且用户不得不重新选择,那也没什么大不了的。您能否包括@Lob/@Type 解决方案的外观?谢谢!
    • 是的,它应该可以工作。该列应该是二进制列。请注意,如果数据损坏,用户将无法执行任何操作:每次加载实体时都会引发异常。
    • 啊...好吧,那肯定是个问题
    • 最安全的解决方案是三列,或者实现一个安全的解析方法(例如,如果解析时抛出任何异常,则返回一个空数组。我会选择三列解决方案。
    【解决方案2】:

    归功于谷歌为“hibernate persist array”返回的第一个链接:你可能需要this。本质上,它表示您需要为此将自己的序列化程序插入 Hibernate。由于我不是 Hibernate 专家,我不知道如何在注释中表达这一点。

    简单得多,但不那么优雅:根本不序列化int[],而是将其数据以序列化形式保存在AdminSettings 中,例如,在带有自定义分隔符的字符串中(呃)。或者同时拥有int[] 和序列化形式,但是支持它们之间的一致性需要更多的内存和更多的CPU。

    【讨论】:

    • 是的,这就是我要问的。我以前在 NHibernate 中做过这个,但不知道如何在这里表达它。另外,我希望(天哪,就这样吧)有一些标准的序列化程序可以处理整数数组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-24
    • 2011-07-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多