使用Set <enum []>进行Hibernate奇怪的行为

时间:2016-10-03 13:28:38

标签: java hibernate

所以我试图保存一个枚举类型为Enum的字段。

基本上是: Set<Color[]>

现在,对于单个枚举,我使用了注释

@ElementCollection(targetClass = Color.class, fetch = FetchType.EAGER)

那没关系,所以我试图使用

@ElementCollection(targetClass = Color[].class, fetch = FetchType.EAGER) private Set<Color[]> availableColorCombinations;

在我的领域,但我有一些奇怪的行为。我在这里只写了6个值:

        colors.add(new Color[] {Color.CHROM, Color.CHROM});
        colors.add(new Color[] {Color.BIANCO, Color.WHITE});
        colors.add(new Color[] {Color.GOLD, Color.GOLD});
        colors.add(new Color[] {Color.NERO, Color.BLACK});
        colors.add(new Color[] {Color.BLACK, Color.BLACK});
        colors.add(new Color[] {Color.WHITE, Color.WHITE});

但是我的目标(当我从数据库中取出它时)说,我在这个Set中有超过200个数组,这是6个值但添加了很多次。

这是什么意思,为什么会这样?最重要的是 - 将Set<Enum[]>存储在数据库中的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

问题是,数组没有实现“深度”相等,即,即使两个数组ab具有完全相同的大小和元素,它们也被报告为不同equals实现,很可能会有不同的哈希码:

a.equals(b) => false

由于许多Set实现将依赖于对其元素的对象相等的合适定义,因此他们会认为这些数组是不同的。

观察,如何

public class Dummy {

    public static void main(String[] args) {
        final Object[] a1 = new Object[] { "foo" };
        final Object[] a2 = new Object[] { "foo" };
        System.out.println(a1.equals(a2));
        System.out.println(a1.hashCode());
        System.out.println(a2.hashCode());
    }
}

产生

false
1342443276
769287236

一个可能的解决方案是使用适当的集合而不是数组来保存颜色值。由于Collection应该提供equalshashCode等的正确定义,因此它们可以嵌套。特别是,由于您正在使用枚举常量,您可以尝试Java的内置EnumSet

EnumSet.of(Color.CHROM, Color.CHROM)

而不是

new Color[] {Color.CHROM, Color.CHROM}

然而,Hibernate能否正确解释这个问题是一个不同的问题。