【问题标题】:Primefaces autocomplete ClassCastExceptionPrimefaces 自动完成 ClassCastException
【发布时间】:2013-01-09 17:22:32
【问题描述】:

我正在使用 Spring 3、Hibernate 4 和 JSF 2.0,并且正在尝试进行 primefaces 自动完成。

我在 DAO 类中有以下内容可以从 Oracle 函数中获取值

@Override
    public List<EmployeeDetail> getEmployeeDetails(String employeeNumber) {

        List query = (List)entityManager.createNamedQuery("getEmp")
                .setParameter("empNumber", employeeNumber)
                .getSingleResult();

        return query;

    }

转换器类

public EmployeeNameConverter(

            List<EmployeeDetail> employeeDB, EmployeeDetailService instance,
                    String employeeNumber) {
                if (employeeDetailService == null) {
                    employeeDetailService = instance;
                }
                if (param == null) {
                    param = employeeNumber;
                }
                this.employeeDB = employeeDB;
            }

@Override
    public Object getAsObject(FacesContext arg0, UIComponent arg1,
            String submittedValue) {
        if (submittedValue.trim().equals("")) {
            return null;
        } else {
            try {
                // int number = Integer.parseInt(submittedValue);
                employeeDB = getEmployeeDetailService().getEmployeeDetails(param);
                for (EmployeeDetail emp : employeeDB) {
                    if (emp.getEmployeeNumber() == submittedValue) {
                        return emp;
                    }
                }

            } catch (NumberFormatException exception) {
                throw new ConverterException(new FacesMessage(
                        FacesMessage.SEVERITY_ERROR, "Conversion Error",
                        "Not a valid employee"));
            }
        }

在我的托管豆中

我有完整的方法将employeeDetailService 传递给我的转换器类。

public List<EmployeeDetail> complete(String query) {
        List<EmployeeDetail> suggestions;
        suggestions = new ArrayList<EmployeeDetail>();
        try {
            employee =  (List<EmployeeDetail>) new EmployeeNameConverter(
                    employeeList, employeeDetailService, query);

            for (EmployeeDetail p : employee) {
                if (p.getEmployeeNumber().startsWith(query))
                    suggestions.add(p);
            }
        } catch (Exception e) {
            System.out.println("exc " + e.getMessage());
            e.printStackTrace();
        }

        return suggestions;
    }

JSF 代码

<p:autoComplete value="#{empMB.selectedEmployee}"
                            id="basicPojo" minQueryLength="6" 
                            completeMethod="#{empMB.complete}" var="p"
                            itemLabel="#{p.employeeNumber}" 
                            itemValue="#{p}" converter="#{p.employee}"
                            forceSelection="true" />

当我输入字符时出现异常

EmployeeNameConverter cannot be cast to java.util.List
java.lang.ClassCastException: net.test.util.EmployeeNameConverter cannot be cast to java.util.List

我该如何解决这个问题?这是正确的方法还是有人可以提出更好的方法来实现相同的目标?

更新 1

@Override
    public List<EmployeeDetail> getEmployeeDetails(String employeeNumber) {

        List query = (List)entityManager.createNamedQuery("getEmp")
                .setParameter("empNumber", employeeNumber)
                .getSingleResult();

        return query;

    }

例外

net.test.entity.EmployeeDetail cannot be cast to java.util.List
java.lang.ClassCastException: net.test.entity.EmployeeDetail cannot be cast to java.util.List
    at net.test.dao.EmployeeDetailDAOImpl.getEmployeeDetails(EmployeeDetailDAOImpl.java:36)

异常行是

List query = (List)entityManager.createNamedQuery("getEmp")
                    .setParameter("empNumber", employeeNumber)
                    .getSingleResult();

【问题讨论】:

  • p.employee 应该是转换器还是 DTO 的实现?
  • @kolossus 如何引用转换器类的员工变量?因为如果我直接作为员工提供,那么我会收到一个错误,因为我的
  • @Polppan,为了消除可能的原因,1) 使用 @ManagedBean 注释您的转换器,以便能够注入数据源(可能是 EJB?) 2) 尝试重构您的转换器以在没有构造函数的情况下执行论据。这是您的代码中转换器与 List 有任何关系的唯一点(我认为),并且从异常情况来看,它是导致转换阻塞的 List 强制转换。您能否具体指出在转换代码中的哪一点引发了异常?
  • @Polppan,那是你的问题。您绝对没有必要手动实例化转换器,更不用说尝试将其转换为任何类型的List。管理和实例化转换器是容器的责任。
  • @Polppan,是的。这不是最佳做法(我似乎忘记了具体是什么),但它会起作用。

标签: spring hibernate jsf primefaces


【解决方案1】:

这里有两个主要问题

  1. 您正在尝试手动实例化和管理 JSF 转换器实例。不要这样做。转换器是一个设计为仅供 JSF 上下文使用的构造。调用new 或向转换器类提供构造函数参数不是开发人员的工作。根据this example 实现一个简单的转换器并在&lt;p:autoComplete/&gt; 上进行配置

    从您的 cmets 来看,您手动管理转换器的原因是能够访问您的 DAO 层。作为一种解决方法,您可以将@ManagedBean 添加到您的转换器中,JSF 会将其视为托管 bean 转换器。作为托管 bean,您现在可以将您的 DAO 资源注入其中。这不是最佳实践,而只是一种解决方法。不过,JSF2.2 中将取消对转换器的这种限制:)。

  2. 在操作转换器时,您试图将其视为常规 POJO 并因此尝试将其转换为几种不兼容的类型

     employee = (List<EmployeeDetail>) new EmployeeNameConverter( employeeList, employeeDetailService, query); //EmployeeNameConverter !instanceof EmployeeDetail
    

【讨论】:

    猜你喜欢
    • 2014-04-11
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    • 1970-01-01
    相关资源
    最近更新 更多