Почему скрытый ввод вызывает ClassCastException - PullRequest
0 голосов
/ 23 января 2012

Рассмотрим этот пример.

Веб-страница :

<h:form>
  <h:outputLabel value="Enter some text:"/>
  <h:inputText value="#{testController.vo.testString}" />
  <h:inputHidden id="test" value="#{testController.vo.id}" />
  <h:commandButton value="Click me" action="#{testController.submitForm}"/>
</h:form>

Контроллер

@Named
@SessionScoped
public class TestController implements Serializable {

    private static final long serialVersionUID = 1L;

    private ValueObject vo = new ValueObject();

    public String submitForm() {
        return null;
    }

    public ValueObject getVo() {
            return vo;
    }

    public void setVo(ValueObject vo) {
        this.vo = vo;
    }

}

ValueObject :

public class ValueObject {

    private Long id;

    private String testString;

    public String getTestString() {
        return testString;
    }

    public void setTestString(String testString) {
        this.testString = testString;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

}

Как видите, класс ValueObject имеет setId / getId методы. Пока все хорошо.

Теперь я хочу представить интерфейс:

public interface Identifiable<T> {
    T getId();
    void setId(T id);
}

и пусть мой ValueObject его осуществит:

public class ValueObject implements Identifiable<Long> { // remainder omitted }

Ничего не изменилось в классе ValueObject, а теперь он реализует Identifiable. Но когда я снова пытаюсь отправить форму, я получаю следующую трассировку стека:

Caused by: javax.el.ELException: /index.xhtml @16,61 value="#{testController.vo.id}": java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long
    at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:139)
    at javax.faces.component.UIInput.updateModel(UIInput.java:818)
    ... 34 more
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long
    at com.test.vo.ValueObject.setId(ValueObject.java:1)  

Как видите, во время обновления значений модели фаза ClassCastException выбрасывается при попытке вызвать метод setId. Это происходит только для скрытых входов. Если я попытаюсь изменить мой xhtml , добавив конвертер , все будет работать нормально:

<h:inputHidden id="test" value="#{testController.vo.id}" converter="javax.faces.Long"/>

Итак, почему поведение ввода изменяется, когда я просто заставляю свой ValueObject реализовать интерфейс с универсальным параметром? Это ошибка Glassfish?

Edit:
Оказалось, что это не зависит от того, скрыт ли или нет. Версия Glassfish, для которой эта проблема воспроизводима: 3.1-b43 .

...