【问题标题】:Using a Java enum in a Spring MVC app?在 Spring MVC 应用程序中使用 Java 枚举?
【发布时间】:2015-07-09 22:31:44
【问题描述】:

所以,我在我的一个 Hibernate 对象中创建了这个枚举,而不是在数据库中创建 LUT:

@Entity
@Table(name = "Foo", schema = "dbo")
public class Foo 
{
    private static final long serialVersionUID = 2L;

    int idFoo;
    String name;
    String type;

    public Foo() 
    {
    }

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "idFoo", unique = true, nullable = false)
    public int getID() { return idFoo; }    
    public void setID(int idFoo) { this.idFoo = idFoo; }

    @Column(name="name", nullable=false, length=50)
    public String getName() { return this.name; }
    public void setName(String aString) { this.name = aString; }

    @Column(name="type", nullable=false, length=8)
    public String getType() { return this.type; }
    public void setType(String aString) { this.type = aString; }

    public static enum FooType
    {
        First,
        Middle,
        Last;

        public boolean isLast() { return this == Last; }
    }
}

对于我的一生,我无法让 Spring 喜欢它。不管我做什么,我都会收到以下错误消息:

Caused by: java.lang.NoSuchMethodException: com.bar.orm.FooType.<init>()
        at java.lang.Class.getConstructor0(Class.java:2810) [rt.jar:1.7.0_45]
        at java.lang.Class.getDeclaredConstructor(Class.java:2053) [rt.jar:1.7.0_45]
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:67) [org.springframework.beans-3
.1.1.RELEASE.jar:3.1.1.RELEASE]
        ... 23 more

在示例中,第一行将引用Foo.$1,而不是命名的枚举。

我尝试过的事情:

  • 从声明中删除静态
  • 给它一个构造函数(不能公开,但 Spring 可以通过反射看到包私有)
  • 将其移至单独的类文件
  • 将其更改为静态最终字符串并移至 JDK 1.7 以使用 switch(String)

只有最后一个有效。 Spring 限制我使用 Java 语言中非常酷的部分真的很糟糕。但这可能不是 Spring 的错,不是吗?我做错什么了?我如何编写上面的枚举,以便 Spring 要么不理它,要么让我使用它?

编辑:

目前,工作解决方案包括以下内容:

  • 每个枚举都在其自己的类文件中,而不是保持其值的对象的内部类。 (这两种方法都有有效的设计原则,但总的来说,重量大致相当。)
  • 枚举被添加到context:component-scan 中的context:exclude-filter 标记中,其正则表达式几乎等同于类名。所有其他枚举都在也被排除在外的包中。
  • 当枚举用于switch 语句时,javac 使用内部类命名方案(more info)为其创建一个特殊类。由于开关使用枚举,因此还必须将生成的类添加到排除过滤器中:“MyClass.1”等。

我正在编辑这个问题,因为我仍然无法相信这不是 Spring 缺乏经验的结果(最后一个荒谬的要求只是把船翻了!),仍然希望得到一个答案,显示“正确”的方式让Spring 用这个核心语言特性做正确的事!

【问题讨论】:

  • 请发布完整的堆栈跟踪。
  • @SotiriosDelimanolis 完整的堆栈跟踪是巨大的;上面的 sn-p 是最后一个“由”部分。但是,我将复制并发布。 (有没有办法扩展“23 more”部分?)
  • 啊,这里解释一下23个stackoverflow.com/questions/7597797/…
  • 如果它很大也没关系,如果你把它作为 cod 发布(在编辑模式下用 {} 按钮换行),Stack Overflow 会添加滚动。
  • 好的,我已经决定完整的堆栈跟踪是无关紧要的——我提供的摘录是 Spring 的基本问题。如果您想重现,只需使用方法创建一个枚举 - 我的猜测是 Spring 无法处理此语言功能。

标签: java spring spring-mvc enums


【解决方案1】:

我会将枚举移动到它自己的文件中,这样你就可以在其他地方访问它而无需指定你的类。

public enum FooType{
    First,
    Middle,
    Last
}

将@Enumerated(EnumType.STRING) 添加到您对枚举的使用中

@Enumerated(EnumType.STRING)
private FooType type;

【讨论】:

  • 为什么需要您建议的任何内容?
  • 我同意企鹅的建议。 foo 类用于 Hibernate 将表映射到数据库,它可能不知道如何处理 enum 属性。
猜你喜欢
  • 2014-02-26
  • 2021-06-19
  • 2023-04-11
  • 2010-10-28
  • 1970-01-01
  • 2019-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多