0

私は次の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>
...

これらはすべて、データ テーブルの行が選択されたときに読み込まれるダイアログ ボックスにあります。次のように関連する 2 つの 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 には次の Converter を使用します。

@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)

私が間違ってやっているアイデアはありますか?

4

1 に答える 1

4

ビュー スコープ Bean はシリアライズ可能である必要があります。これは、HTTP セッションに保存され、通常の Java オブジェクト参照としてメモリ内に保存されるのではなく、ディスク ファイル システムにシリアライズされた形式で保存されるか、サーバーでセッションを共有するためにネットワーク経由で転送されるためです。集まる。

シリアルImageTypeConvert化する必要がないように、ビュー スコープ Bean の代わりにリクエスト スコープ Bean を作成します。

@RequestScoped
@ManagedBean
public class ImageTypeConvert implements Converter {

または、シリアライズ可能に実装させます:

@ViewScoped
@ManagedBean
public class ImageTypeConvert implements Converter, Serializable {

FacesContextところで、深刻な設計上の問題があります。クラスのインスタンス変数として決して代入してはいけません。これはスレッドセーフではありません。それらcontextmybean宣言をメソッド ブロック内に移動します。

@FacesConverterまた、 でマネージド Bean として使用する場合は、とにかく使用されたことがないため、アノテーションを削除したことにも注意してください#{imageTypeConvert}nameまた、基本的にデフォルト値を繰り返しているため、マネージド Bean のを削除したことにも注意してください。

于 2013-04-17T12:30:44.183 に答える