与Enum的JPA(Eclipselink)ElementCollection

时间:2013-07-12 17:10:40

标签: java-ee jpa eclipselink

我想将一个选定的枚举列表添加到我的一个JPA实体中:

@Entity
public class FooEntity {
    ...
    List<SecurityType> securityTypes;

    @ElementCollection(targetClass = SecurityType.class)
    public List<SecurityType> getSecurityTypes() {
        return securityTypes;
    }

    public void setSecurityTypes(List<SecurityType> securityTypes) {
        this.emum1s = securityTypes;
    }
    ...
}

使用Enum

public enum SecurityType {
    FOO, BAR
}

我已根据JPA的默认行为将数据模型添加到我的数据库。

不幸的是,我将这种类型的对象保存到DB时收到异常:

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Enum
at org.eclipse.persistence.mappings.converters.EnumTypeConverter.convertObjectValueToDataValue(EnumTypeConverter.java:160)
at org.eclipse.persistence.mappings.DirectCollectionMapping.postInsert(DirectCollectionMapping.java:2209)
at org.eclipse.persistence.descriptors.DescriptorQueryManager.postInsert(DescriptorQueryManager.java:980)
at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:480)

正如您所看到的,例外来自JPA。我有点惊讶,因为我确实有一个enum类型的对象&#34; SecurityType&#34;以Integer(默认行为)写入数据库,不应以 String 的强制转换为 Enum (因为该对象已经是枚举)。

我开始调试,发现自动生成的JPA代理对象不包含 List&lt; Enum1&gt; 属性,而是 List&lt; String&gt;

Debugging information of NetBeans

对我来说,这看起来像一个错误,我发现了一个描述这个主题的问题:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=328371

我尝试使用默认的Glassfish 3.1.2.2(Eclipselink 1.3)和Eclipselink 1.4。两者都是一样的。

任何人都可以使用JPA @ElementCollections中的枚举帮助吗?这是一个错误还是我错过了什么?

谢谢!

2 个答案:

答案 0 :(得分:0)

没有1.3或1.4版本,你的意思是2.4吗? 2.5中的最新版本,所以你可能想尝试一下。

EclipseLink不会自动生成代理,因此您正在查看您的类,就像您定义的那样。检查你编译/部署了你的代码,它是否用作String?

你是如何构建插入的对象的?检查您是否没有将字符串添加到集合中,它似乎就是您。

答案 1 :(得分:0)

除了PurchaseOrderHistory批注外,还使用Uservar purchaseOrder = await _context.PurchaseOrder .Include(p => p.Division) .Include(p => p.PaymentType) .Include(p => p.Status) .Include(p => p.Vendor) .Include(p => p.ItemServiceLine) .Include(p => p.User) .Include(p => p.PurchaseOrderHistory) .ThenInclude(poh => poh.User) .FirstOrDefaultAsync(m => m.ID == id); (指向映射表的名称并包含joinColumn)和@ElementCollection(fetch = FetchType.EAGER)(指定表中@Enumerated(EnumType.String)的{​​{1}}列的名称)