Исключение преобразования даты внутри составного компонента JSF - PullRequest
1 голос
/ 30 мая 2011

Когда я получаю доступ к значению управляемой даты JPA из JSF, оно возвращается с javax.faces.component.UdateModelException, говорящим

'Cannot convert 01.01.10 00:00 of type class java.util.Date to class org.apache.openjpa.util.java$util$Date$proxy 

Использование значения даты, управляемого JPA (что означает, что он проксируется), прекрасно работает, когда оно используется непосредственно из EL, например:

'<h:outputLabel value="MyDateValue" for="input"/> 
'<h:inputText id="inputDate" value="#{bean.myDate}"/> 

Тем не менее, это вызывает проблемы при попытке использовать его с составными компонентами и возвращает следующее исключение конвертера и, следовательно, не может обновить модель ...

(упрощенный) составной компонент JSF inputDate.xhtml

    <head> 
            <title>A date input field</title> 
    </head> 

    <composite:interface> 
            <composite:attribute name="dateValue"/> 
    </composite:interface> 

    <composite:implementation> 
            <h:outputLabel value="MyDateValue" for="input"/> 
            <h:inputText id="input" value="#{cc.attrs.dateValue}"/> 
    </composite:implementation> 

Предположение: Кажется, что замена прокси в OpenJPA обрабатывается по-разному, когда к значению обращаются из композита. Я предполагаю, что EL-resolver по-разному обрабатывает вызовы значений объекта, когда они передаются в композиты. Передача его в композиты означает, что к нему сначала осуществляется доступ в композите, что слишком поздно, и необходимая замена прокси не выполнена (таким образом, исключение конвертера)

Итак, я попытался изменить язык выражений для MyFaces, но он не работал в Websphere, хотя я изменил загрузку класса на родительский последний и предоставил el-impl и el-api из glassfish в папке lib и вставил необходимый контекст-параметр для MyFaces

Как вы, ребята, используете управляемые JPA даты (или другие прокси-объекты) в составных компонентах ???

Ответы [ 2 ]

1 голос
/ 25 января 2012

Если вы используете реализацию Sun EL, вы можете использовать следующий ELResolver, который решает эту проблему:

public class BugfixELResolver extends ELResolver {
//...
@Override
public Class<?> getType(ELContext anElContext, Object aBase, Object aProperty) {
    if (aBase.getClass().getCanonicalName().equals("com.sun.faces.el.CompositeComponentAttributesELResolver.ExpressionEvalMap")){
        Object tempProperty=((Map)aBase).get(aProperty);
        if (tempProperty!=null&&tempProperty.getClass().getCanonicalName().equals("org.apache.openjpa.util.java.util.Date.proxy")) {
            anElContext.setPropertyResolved(true);
            return java.util.Date.class;
        }
    }
    return null;
}


}

Добавьте его в face-config следующим образом:

<el-resolver>
    xxx.BugfixELResolver
</el-resolver>

Этот обходной путь также может использоваться в средах, где вы не можете изменить реализацию EL (например, websphere и т. Д.).

1 голос
/ 31 мая 2011

Вот обходной путь. Кажется, проблема в реализации ExpressionLanguage WebSpheres или, скорее, выполняются решатели порядка. Регистрация реализации JBoss EL работает и разрешает прокси даты перед вызовом составного компонента. Я также пробовал Glassfish EL, но он тоже не работал ...

Регистрация альтернативного EL довольно странная: настройка в web.xml для MyFaces -

<context-param>
   <param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
   <param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>

Дополнительно в WebContent/META-INF/services/ необходим файл с именем javax.el.expressionFactory с этой единственной строкой org.jboss.el.ExpressionFactoryImpl. Класс приходит от jboss-el-2.0.2.CR1.jar (извините, не удалось найти ссылку на репозиторий Maven)

Я буду держать вас в курсе, когда найду лучшее решение ...

...