野蝇——在可嵌入bean中使用枚举



我想在实体bean中使用enum。但是枚举是在一个嵌入对象中。这里有代码:

@Entity
@Table(name = "entity_foo")
public class EntityFoo implements Serializable
{
   @Embedded
   private EmbeddedFoo embeddedFoo;
   public EmbeddedFoo getEmbeddedFoo()
   {
      return embeddedFoo;
   }
   public void setEmbeddedFoo(final EmbeddedFoo embeddedFoo)
   {
      this.embeddedFoo = embeddedFoo;
   }
}

我的嵌入式对象包含枚举,看起来像这样:

@Embeddable
public class EmbeddedFoo implements Serializable
{
    public static enum EnumBar {
        VALUEA,VALUEB
    }
    private EnumBar enumBar;
    @Enumerated(EnumType.STRING)
    public EnumBar getEnumBar()
    {
        return enumBar;
    }
    public void setEnumBar(final EnumBar enumBar)
    {
        this.enumBar = enumBar;
    }
}

在entity_foo表中,我声明enumbar值为varchar(255)。现在我试着从数据库中获取数据。

final List<EntityFoo> entityFoos = query.getResultList();

抛出一个PSQLException:

Caused by: org.postgresql.util.PSQLException: Bad value for type int : VALUEA

如果我直接在实体"EntityFoo"中使用枚举,它可以正常工作。此代码运行在Wildfly 8.1, Postgres 9.3和Java 1.7

我希望我清楚地说明了我的问题,任何人都可以帮助我。

这是到一个小型项目存储库的链接https://github.com/MotherCake/miniprojct

要使用这个项目,您需要一个表。下面是create语句。

CREATE TABLE "public"."minitable"(id int PRIMARY KEY NOT NULL,enumbar varchar(255));
CREATE UNIQUE INDEX minitable_pkey ON "public"."minitable"(id);
INSERT INTO minitable (id,enumbar) VALUES (0,'VALUEA');
INSERT INTO minitable (id,enumbar) VALUES (1,'VALUEB');

我忘了说的是,我正在使用Toplink。我认为是topplink造成了这个问题。

在Testservlet类中,您可以看到创建查询的两种不同方式。如果我使用createQuery(..)方法和setParameter(..)方法,就会抛出我所描述的异常。这是在评论里。

如果我使用createNativeQuery方法,我得到结果列表,没有异常被抛出。但在此之后,我得到ClassCastException类TestServlet。

问题是默认情况下,使用original将枚举保存为int。您必须通过在enum字段上添加@Enumerated(EnumType.STRING)来将其更改为字符串表示。还要检查在你的主实体中,你已经注释了字段,而不是getter/setter,所以它打开了对实体以及嵌入式实体的字段访问(在本例中为EmbeddedFoo)。如果你在EmbeddedFoo字段而不是getter中注释它会正确工作。

@Embeddable
public class EmbeddedFoo implements Serializable
{
    public static enum EnumBar {
        VALUEA,VALUEB
    }
    @Enumerated(EnumType.STRING)
    private EnumBar enumBar;
    public EnumBar getEnumBar()
    {
        return enumBar;
    }
    public void setEnumBar(final EnumBar enumBar)
    {
        this.enumBar = enumBar;
    }
}

另外,如果你必须在getter上有注释,因为某些原因你必须注释EmbeddedFoo @Access(AccessType.PROPERTY),它也会解决你的问题。

@Embeddable
@Access(AccessType.PROPERTY)
public class EmbeddedFoo implements Serializable
{
    public static enum EnumBar {
        VALUEA,VALUEB
    }
    private EnumBar enumBar;
    @Enumerated(EnumType.STRING)
    public EnumBar getEnumBar()
    {
        return enumBar;
    }
    public void setEnumBar(final EnumBar enumBar)
    {
        this.enumBar = enumBar;
    }
}

我找到了一个解决方案来让项目工作,但我不知道为什么这是必要的。我认为,正如Jakub所写的,添加@ EnumType.STRING 应该就足够了。

我用@Column(name = " enumBar ")注释了变量enumBar。

@Column(name = "enumbar")
@Enumerated(EnumType.STRING)
public EnumBar enumBar;

此外,我在EntityFoo

中为嵌入对象添加了@AtributeOverride注释。
@Embedded
@AttributeOverride(name = "enumBar", column = @Column(name = "enumbar"))
private EmbeddedFoo embeddedFoo;

之后,它就像魅力一样。

我在github上为每个想尝试的人更新项目。

相关内容

  • 没有找到相关文章

最新更新