Reputation: 617
i have the following JSF form:
...
<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>
...
All these are in a dialog box loaded when a row of a data table is selected. I have two Hibernate entities which are related as follows:
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;
and 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;
I use the following Converter for the 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;
}
}
and finally my BackBean:
@ManagedBean(name = "syncCenterBean")
@ViewScoped
public class SyncCenterBean implements Serializable {
@PostConstruct
public void init(){
cRImageTypeList = getImageTypesDB();
cRImageType = new CRImageType();
cRImageDataList = populateImageOnlyToDataWarehouseList(getImageDataSOAP());
cRImageDataListLocal = getImageDataDB();
}
...
But when i try to load the datatabe i get the following error:
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)
Any ideas what i have been doing WRONG?
Upvotes: 0
Views: 956
Reputation: 1108732
View scoped beans must be serializable because they're stored in HTTP session which in turn can be stored in serialized form in disk file system instead of as normal Java object references in memory, or be transferred over network in order to share sessions in a server cluster.
Either make the ImageTypeConvert
a request scoped bean instead of a view scoped bean, so that it don't require to be serialized:
@RequestScoped
@ManagedBean
public class ImageTypeConvert implements Converter {
Or let it implement serializable:
@ViewScoped
@ManagedBean
public class ImageTypeConvert implements Converter, Serializable {
You've by the way a severe design problem: you should never, never assign FacesContext
as an instance variable of a class. This is not threadsafe. Move those context
and mybean
declarations to inside the method block.
Also note that I removed the @FacesConverter
annotation as it's never been used anyway if you use it as a managed bean by #{imageTypeConvert}
. Also note that I removed the name
of the managed bean as you're basically repeating the default value.
Upvotes: 4