当我从JSF访问JPA托管日期值时,它返回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中不起作用,即使我最后将类加载更改为父级,并在lib文件夹中提供了来自glassfish的el-impl和el-api并插入MyFaces的必要上下文参数
你们如何在复合组件中使用JPA管理的日期(或其他代理实体)?
答案 0 :(得分:1)
这是解决方法。问题似乎是WebSpheres的ExpressionLanguage实现,或者更确切地说是执行了顺序解析器。在调用复合组件之前,注册JBoss EL实现可以工作并解析日期代理。我也尝试过Glassfish EL,但它也不起作用......
注册替代EL非常奇怪:MyFaces的web.xml中的设置是
<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 repo的链接)
一旦找到更好的解决方案,我会及时通知您。
答案 1 :(得分:1)
如果您正在使用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;
}
}
以这种方式将它添加到faces-config:
<el-resolver>
xxx.BugfixELResolver
</el-resolver>
此解决方法也可用于无法更改EL实现的环境(如websphere等)。