【问题标题】:Using enum in selectOneMenu fails with: 'Male' must be convertible to an enum [duplicate]在 selectOneMenu 中使用枚举失败:“男性”必须可转换为枚举 [重复]
【发布时间】:2013-01-31 07:49:00
【问题描述】:

我正在开发一个小型 jsf 项目,我到达了一个状态,我必须在枚举类型中存储一个值,但不知道如何处理

所以我在这里发布我的问题的一个小描述:

这里是枚举类型:

 package com.enumeration;

 import java.io.Serializable;


 public enum Gender implements Serializable{

    Male('M'), Female('F');

    private char description;

   private Gender(char description) {
     this.description = description;
   }

   public char getDescription() {
     return description;
   }

}

xhtml 页面:

    <h:panelGrid columns="2">
                <h:outputLabel value="Nom:" for="nom" />
                <h:inputText id="nom" value="#{employee.newEmployee.nom}" title="Nom" />

                <h:outputLabel value="Gender:" for="gender" />
                <h:selectOneMenu value="#{employeeBean.newEmployee.gender}" id="gender">
                     <f:selectItem itemLabel="Male" itemValue="Male" />
                    <f:selectItem itemLabel="Female" itemValue="Female"/>
                </h:selectOneMenu>

            </h:panelGrid>
            <h:commandButton value="ajouter" action="index.xhtml" actionListener="#{employeeBean.ajouter}" />
        </h:form>

问题是当我尝试向数据库添加新行时,jsf 抛出错误:j_idt7:gender: 'Male' must be convertible to an enum.

我在网上做了一些搜索,但无法理解解决方案 请帮忙 谢谢

【问题讨论】:

    标签: jsf enums selectonemenu


    【解决方案1】:

    在我的实体中:

    @Entity
    
    public class MyClass {
    @Column
    @Convert(converter = MyEnumConverter.class)
    @Enumerated(EnumType.ORDINAL)
    private MyEnumType myEnumType;
    //....getter and setter    }
    

    在我的枚举中:

    public enum MyEnumType {
        AAAA,
        BBBB;
    public String getLabel() {
        switch (this) {
            case AAAA:
                return "aaaa";
            case BBBB:
                return "bbbb";
    
        }
        return "NONE";
    }
    @Override
    public String toString() {
        return getLabel();
    }
    }
    

    另一个枚举:

    public enum AnotherEnum {
          ...
    }
    

    在我的转换器中:(它不是一个 FacesConvertor)。

    @Converter
    public class MyEnumConvertor implements AttributeConverter<MyEnumType, Byte> {
        @Override
        public Byte convertToDatabaseColumn(MyEnumType attribute) {
            switch (attribute) {
                case AAAA:
                    return 0;
                case BBBB:
                    return 1;
                default:
                    throw new IllegalArgumentException("Unknown" + attribute);
            }
        }
        @Override
        public MyEnumType convertToEntityAttribute(Byte dbData) {
            switch (dbData) {
                case 0 :
                    return EstatePossessionType.AAAA;
                case 1:
                    return EstatePossessionType.BBBB;
    
                default:
                    throw new IllegalArgumentException("Unknown" + dbData);
            }
        }
      }
    

    在我的 util 类中:

    public class MyUtilClass {
        public <T extends Enum> SelectItem[]     createSelectItemByEnumClass(Class<T> clazz) throws Exception {
            SelectItem[] selectItem = null;
            int i = 0;
            try {
              Object[] enumConstants = clazz.getEnumConstants();
                if (enumConstants != null) {
                    selectItem = new SelectItem[enumConstants.length];
                    for (Object object : enumConstants) {
                        selectItem[i++] = new SelectItem(object,     object.toString());
                  }
                }
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            return selectItem;
        }
    }
    

    在我的 CDI-bean 类中:

    public class MyCdiClass {
        MyEnumType selectByUser = null;
        public Class getSelectItemClass(){
            return MyEnumType.class;//<<--I'll tell jsf, I want create SelectItem from this class.Maybe I have more than one enum:).
        }
        public MyEnumType getSelectByUser() {
            return selectByUser;
        }
        public void setSelectByUser(MyEnumType selectByUser) {
            this.selectByUser = selectByUser;
        }
    }
    

    在我的 jsf 页面中:

    <h:selectOneMenu value="#{handleEstateActionInEstate.selectByUser}">
        <f:selectItems value="#{myUtility.createSelectItemByEnumClass(myCdiBean.selectItemClass)}"/>
     </h:selectOneMenu>
    

    我希望这些 sn-p 有用。

    【讨论】:

      【解决方案2】:

      您的问题是您的 &lt;f:selectItem&gt; 指定了字符串,而在 &lt;h:selectItem value="#{employeeBean.newEmployee.gender}"&gt; 中似乎返回了两个 Gender 枚举之一。

      只要将相同的值粘贴到两个枚举中,枚举就可以直接转换为 AFAIK。

      这是 /a 模式:

      <h:selectOneMenu value="#{employeeBean.newEmployee.gender}" id="gender">
          <f:selectItems value="#{enumValuesProvider.genders}"
                         var="gender"
                         itemValue="#{gender}"
                         itemLabel="#{gender.name()}" />
      </h:selectOneMenu>
      

      注意,我在这里使用&lt;f:selectItems&gt;。问题是,您不能简单地直接从 JSF 页面获取值。您将需要一个专用的 bean 来完成这项工作:

      @Named      // or @ManagedBean if you're not using CDI
      @ViewScoped // or @RequestScoped
      public EnumValuesProvider implements Serializable
      {
          public Gender[] getGenders()
          {
              return Gender.values();
          }
      }
      

      这只是写下来,没有任何测试。没有任何保证。

      【讨论】:

      • 嗨,谢谢你的帮助,我做了如下 并且 i > 错误“j_idt20:gender: 'F' must be convertible to an enum.”
      • 可能你有一个空值的“选择”项,或者类似的东西
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-04
      • 2020-08-21
      • 2021-01-04
      • 1970-01-01
      • 2012-08-31
      相关资源
      最近更新 更多