我有以下JSF表单:
...
<p:column>
<h:outputText value="Image Id:" style="font-weight:bold; padding-right:10px" />
</p:column>
<p:column>
<h:outputText value="#{syncCenterBean.selectedCRImageData.imId}" />
</p:column>
</p:row>
....
<p:row>
<p:column>
<h:outputText value="Image Type" style="font-weight:bold; padding-right:10px" />
</p:column>
<p:column>
<p:selectOneMenu id="imtype" value="#{syncCenterBean.cRImageType}" converter="#{imageTypeConvert}">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{syncCenterBean.cRImageTypeList}" var="cRImageType" itemValue="#{cRImageType.imTypeId}" itemLabel="#{cRImageType.imTypeName}" />
</p:selectOneMenu>
</p:column>
</p:row>
...
当选择一行数据表时,所有这些都在加载的对话框中。我有两个相关的Hibernate实体如下:
CRImageData
@Entity
@Table(name = "imageviewer_crimagedata")
public class CRImageData implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
@Column(name = "ImId")
private Long imId;
@Column(name = "ImName")
private String imName;
@Column(name = "ImTypeId")
private Long imTypeId;
@Column(name = "ImPatientId")
private String imPatientId;
@Column(name = "ImStatus")
private String imStatus;
@Column(name = "imFormat")
private String imFormat;
@ManyToOne
@JoinColumn(name="ImTypeId",insertable=false,updatable=false)
private CRImageType cRImageType;
和CRImageType
@Entity
@Table(name = "imageviewer_crimagetype")
public class CRImageType implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
@Column(name = "ImTypeId")
private Long imTypeId;
@Column(name = "ImTypeName")
private String imTypeName;
@Column(name = "ImTypeDescription")
private String imTypeDescription;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="imageviewer_imtype_variable",
joinColumns={@JoinColumn(name="ImTypeId")},
inverseJoinColumns={@JoinColumn(name="VarId")})
private Set<CRVariable> crvariables = new HashSet<CRVariable>();
@OneToMany(mappedBy="cRImageType")
private Set<CRImageData> cRImageData;
我为selectOneMenu使用以下转换器:
@ViewScoped
@ManagedBean(name = "imageTypeConvert")
@FacesConverter(forClass=CRImageType.class,value="imageTypeConvert")
public class ImageTypeConvert implements Converter {
@ManagedProperty(value="#{syncCenterBean}")
private SyncCenterBean syncCenterBean;
FacesContext context = FacesContext.getCurrentInstance();
SyncCenterBean mybean = (SyncCenterBean) context.getExternalContext().getSessionMap().get("syncCenterBean");
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value{
Long imTypeId = Long.parseLong(value.trim());
List<CRImageType> cRImageTypeList = mybean.getcRImageTypeList();
for (CRImageType cRImageType:cRImageTypeList) {
if(cRImageType.getImTypeId().compareTo(imTypeId)==0){
return cRImageType;
}
}
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
System.out.println("!!!!!! (2) Into getAsString");
return Long.toString(((CRImageType) value).getImTypeId());
}
public SyncCenterBean getSyncCenterBean() {
return syncCenterBean;
}
public void setSyncCenterBean(SyncCenterBean syncCenterBean) {
this.syncCenterBean = syncCenterBean;
}
}
最后是我的BackBean:
@ManagedBean(name = "syncCenterBean")
@ViewScoped
public class SyncCenterBean implements Serializable {
@PostConstruct
public void init(){
cRImageTypeList = getImageTypesDB();
cRImageType = new CRImageType();
cRImageDataList = populateImageOnlyToDataWarehouseList(getImageDataSOAP());
cRImageDataListLocal = getImageDataDB();
}
...
但是当我尝试加载数据时,我收到以下错误:
javax.portlet.faces.BridgeException: javax.faces.FacesException: com.forth.actions.ImageTypeConvert
at com.liferay.faces.bridge.BridgePhaseRenderImpl.execute(BridgePhaseRenderImpl.java:98)
at com.liferay.faces.bridge.BridgeImpl.doFacesRequest(BridgeImpl.java:99)
...
Caused by: java.io.NotSerializableException: com.forth.actions.ImageTypeConvert
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at java.util.HashMap.writeObject(HashMap.java:1001)
任何想法我一直在做什么错?
答案 0 :(得分:4)
查看作用域bean必须是可序列化的,因为它们存储在HTTP会话中,而HTTP会话又可以以序列化形式存储在磁盘文件系统中,而不是作为内存中的普通Java对象引用,或者通过网络传输以共享会话在服务器群集中。
使ImageTypeConvert
成为请求范围的bean而不是视图范围的bean,因此不需要序列化:
@RequestScoped
@ManagedBean
public class ImageTypeConvert implements Converter {
或让它实现serializable:
@ViewScoped
@ManagedBean
public class ImageTypeConvert implements Converter, Serializable {
顺便提一下,你遇到了一个严重的设计问题:你绝不应该永远不要将FacesContext
指定为类的实例变量。这不是线程安全的。将这些context
和mybean
声明移到方法块内。
另请注意,我删除了@FacesConverter
注释,因为如果您将#{imageTypeConvert}
用作托管bean,它仍然无法使用。另请注意,我删除了托管bean的name
,因为您基本上重复了默认值。