设置从 Map 派生的域模型对象的成员
Setting a member of a domain model object derived from Map
我有域模型对象,它带有从映射派生的动态键和值:
public class MyDomainModelObject extends HashMap<String, SomeClass<?>>
{
private String documentType;
public MyDomainModelObject()
{
super();
}
public String getDocumentType()
{
return documentType;
}
public void setDocumentType(final String documentType)
{
this.documentType = documentType;
}
}
正在获取和设置存储在地图中的值。
但是成员documentType
的设置导致ClassCastException
.
documentType
在 primefaces datatable 单元格编辑器中编辑:
<p:dataTable ...>
<p:column ... />
...
</p:column>
<p:column>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{curObj.getDocumentType()}" />
</f:facet>
<f:facet name="input">
<p:selectOneMenu value="#{curObj.documentType}">
<f:selectItems value="#{someBean.determineDocumentTypes(curObj)}" var="curDocType" itemLabel="#{curDocType}"
itemValue="#{curDocType}" />
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
当我更改 table 中的 documentType
时,出现以下异常:
10:08:09,581 ERROR [stderr] (http-/0.0.0.0:9090-3) java.lang.ClassCastException: java.lang.String cannot be cast to SomeObject
10:08:09,581 ERROR [stderr] (http-/0.0.0.0:9090-3) at MyDomainModel.put(MyDomainModel.java:1)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at javax.el.MapELResolver.setValue(MapELResolver.java:262)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at com.sun.faces.el.DemuxCompositeELResolver._setValue(DemuxCompositeELResolver.java:255)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at com.sun.faces.el.DemuxCompositeELResolver.setValue(DemuxCompositeELResolver.java:281)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at de.odysseus.el.tree.impl.ast.AstProperty.setValue(AstProperty.java:156)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at de.odysseus.el.tree.impl.ast.AstEval.setValue(AstEval.java:87)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at de.odysseus.el.TreeValueExpression.setValue(TreeValueExpression.java:146)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at org.jboss.weld.el.WeldValueExpression.setValue(WeldValueExpression.java:64)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:131)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at javax.faces.component.UIInput.updateModel(UIInput.java:832)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at javax.faces.component.UIInput.processUpdates(UIInput.java:749)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1290)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at org.primefaces.component.celleditor.CellEditor.processUpdates(CellEditor.java:89)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at org.primefaces.component.api.UIData.process(UIData.java:379)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at org.primefaces.component.api.UIData.processChildren(UIData.java:360)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at org.primefaces.component.api.UIData.processPhase(UIData.java:322)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at org.primefaces.component.api.UIData.processUpdates(UIData.java:308)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at org.primefaces.component.datatable.DataTable.processUpdates(DataTable.java:722)
10:08:09,584 ERROR [stderr] (http-/0.0.0.0:9090-3) at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:577)
10:08:09,584 ERROR [stderr] (http-/0.0.0.0:9090-3) at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
为什么javax.el.MapELResolver
用来设置documentType
的值?
setDocumentType
方法没有执行但是getDocumentType
。
我有点困惑。
Why is the javax.el.MapELResolver
is used to set the value of documentType
?
因为base是java.util.Map
的实例。基本上,EL 检查如下:
if (curObj instanceof Map) {
// Use MapELResolver.
}
else (...) {
// ...
}
else {
// Use BeanELResolver.
}
您有 2 个选择:
使用组合而不是继承。
public class MyDomainModelObject {
private String documentType;
private Map<String, Foo> properties;
// ...
}
坚持继承并委托给它(hacky、原始类型等)。
public String getDocumentType() {
return (String) ((Map) this).get("documentType");
}
public void setDocumentType(final String documentType) {
((Map) this).put("documentType", documentType);
}
注意EL不会直接使用它。它仍然会通过 Map#get()
通过 MapELResolver
获取它。这些方法将仅由您的域代码使用。它只会在您尝试循环时中断。
我有域模型对象,它带有从映射派生的动态键和值:
public class MyDomainModelObject extends HashMap<String, SomeClass<?>>
{
private String documentType;
public MyDomainModelObject()
{
super();
}
public String getDocumentType()
{
return documentType;
}
public void setDocumentType(final String documentType)
{
this.documentType = documentType;
}
}
正在获取和设置存储在地图中的值。
但是成员documentType
的设置导致ClassCastException
.
documentType
在 primefaces datatable 单元格编辑器中编辑:
<p:dataTable ...>
<p:column ... />
...
</p:column>
<p:column>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{curObj.getDocumentType()}" />
</f:facet>
<f:facet name="input">
<p:selectOneMenu value="#{curObj.documentType}">
<f:selectItems value="#{someBean.determineDocumentTypes(curObj)}" var="curDocType" itemLabel="#{curDocType}"
itemValue="#{curDocType}" />
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
当我更改 table 中的 documentType
时,出现以下异常:
10:08:09,581 ERROR [stderr] (http-/0.0.0.0:9090-3) java.lang.ClassCastException: java.lang.String cannot be cast to SomeObject
10:08:09,581 ERROR [stderr] (http-/0.0.0.0:9090-3) at MyDomainModel.put(MyDomainModel.java:1)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at javax.el.MapELResolver.setValue(MapELResolver.java:262)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at com.sun.faces.el.DemuxCompositeELResolver._setValue(DemuxCompositeELResolver.java:255)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at com.sun.faces.el.DemuxCompositeELResolver.setValue(DemuxCompositeELResolver.java:281)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at de.odysseus.el.tree.impl.ast.AstProperty.setValue(AstProperty.java:156)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at de.odysseus.el.tree.impl.ast.AstEval.setValue(AstEval.java:87)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at de.odysseus.el.TreeValueExpression.setValue(TreeValueExpression.java:146)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at org.jboss.weld.el.WeldValueExpression.setValue(WeldValueExpression.java:64)
10:08:09,582 ERROR [stderr] (http-/0.0.0.0:9090-3) at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:131)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at javax.faces.component.UIInput.updateModel(UIInput.java:832)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at javax.faces.component.UIInput.processUpdates(UIInput.java:749)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1290)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at org.primefaces.component.celleditor.CellEditor.processUpdates(CellEditor.java:89)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at org.primefaces.component.api.UIData.process(UIData.java:379)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at org.primefaces.component.api.UIData.processChildren(UIData.java:360)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at org.primefaces.component.api.UIData.processPhase(UIData.java:322)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at org.primefaces.component.api.UIData.processUpdates(UIData.java:308)
10:08:09,583 ERROR [stderr] (http-/0.0.0.0:9090-3) at org.primefaces.component.datatable.DataTable.processUpdates(DataTable.java:722)
10:08:09,584 ERROR [stderr] (http-/0.0.0.0:9090-3) at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:577)
10:08:09,584 ERROR [stderr] (http-/0.0.0.0:9090-3) at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
为什么javax.el.MapELResolver
用来设置documentType
的值?
setDocumentType
方法没有执行但是getDocumentType
。
我有点困惑。
Why is the
javax.el.MapELResolver
is used to set the value ofdocumentType
?
因为base是java.util.Map
的实例。基本上,EL 检查如下:
if (curObj instanceof Map) {
// Use MapELResolver.
}
else (...) {
// ...
}
else {
// Use BeanELResolver.
}
您有 2 个选择:
使用组合而不是继承。
public class MyDomainModelObject { private String documentType; private Map<String, Foo> properties; // ... }
坚持继承并委托给它(hacky、原始类型等)。
public String getDocumentType() { return (String) ((Map) this).get("documentType"); } public void setDocumentType(final String documentType) { ((Map) this).put("documentType", documentType); }
注意EL不会直接使用它。它仍然会通过
Map#get()
通过MapELResolver
获取它。这些方法将仅由您的域代码使用。它只会在您尝试循环时中断。