Рассмотрим этот пример.
Веб-страница :
<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 .