簡體   English   中英

Wicket SpringBean在一個面板上生成NotSerializableException,但在另一個面板上不生成

[英]Wicket SpringBean generates NotSerializableException on one panel but not another

我有一個Spring bean DAO類,它具有方法reverseLookup(),該方法返回List <String>。 我將此bean注入2個wicket組件中,並在每個組件的ajax調用中調用相同的方法。

在第一個面板中,它工作正常,沒有任何問題。 在第二個面板中,我收到一個NotSerializableException。

DAO類不是可序列化的,但不一定必須是。 我使用@SpringBean注入bean(在這個大型應用程序中還有數十個其他注入@SpringBean的bean都可以正常工作)

在ajax調用完成並且頁面被序列化之前,不會發生該錯誤。 然后,它在每個連續的請求周期失敗。

我看不到DAO類有什么特別的地方-它沒有成員變量或其他DAO類沒有什么特別的地方。 我不明白為什么它在一個面板中效果很好,但在另一個面板中效果不佳。

我曾嘗試在有問題的面板中使用Injector使成員變量變為瞬態,但這並沒有什么不同。

DAO界面:

public interface StringResourceDAO extends EntityDAO<StringResource, Long> {

  .. other methods
  public List<String> reverseLookup( TranslationType p_type, String p_searchString, Locale p_locale, String p_style, String p_variation ) throws GetException;
}

DAO類:

public class StringResourceJpaDAO extends AbstractEntityJpaDAO<StringResource> implements StringResourceDAO {
  ... other methods

  @Override
  public List<String> reverseLookup( TranslationType p_type, String p_searchString, Locale p_locale, String p_style, String p_variation ) throws GetException {
    ViewCriteria<StringResource> resourceCriteria = new ViewCriteria<>();
    resourceCriteria.addFilter( new EqualityFilter<String>( StringResource_.key, Operator.STARTS_WITH, p_type.getPrefix() ) );
    resourceCriteria.addFilter( EqualityFilter.equalFilter( StringResource_.localeCountry, p_locale == null ? null : StringUtils.defaultIfEmpty( p_locale.getCountry(), null ) ) );
    resourceCriteria.addFilter( EqualityFilter.equalFilter( StringResource_.localeLanguage, p_locale == null ? null : StringUtils.defaultIfEmpty( p_locale.getLanguage(), null ) ) );
    resourceCriteria.addFilter( new EqualityFilter<String>( StringResource_.value, Operator.LIKE, "%" + p_searchString + "%" ).setCaseSensitive( false ) );
    resourceCriteria.setDistinctResults( true );
    resourceCriteria.setMaxResults( 250 );

    List<String> matchingKeys = super.getOtherProperty( l_resourceCriteria, StringResource.class, String.class, StringResource_.key.getName() );
    return new ProxyList<String,String>( l_matchingKeys ) {

      private static final long serialVersionUID = 1L;

      @Override
      public String getItem( String p_proxy ) {
        return TranslationType.removePrefix( p_type, p_proxy );
      }

    };
  }

}

AbstractEntityJpaDAO是所有其他DAO實現使用的父類。 ProxyList只是pre-stream()包裝器List的實現,允許訪問列表屬性而不必復制列表的內容。 ViewCriteria充當較低層的JPA與上面用於創建數據查詢的UI邏輯之間的橋梁。

正常工作的組件(不在ModalWindow中的面板):

public abstract class ServiceLevelLookupPanel extends AbstractDialogPanel {

  @SpringBean
  protected StringResourceDAO m_resourceService;

  protected void onInitialize() {
    TextField<String> serviceLevelNumberField = new TextField<String>( "serviceLevelNumberField", m_serviceLevelNumberModel );
    // HAVE to set this to not required, otherwise the onchange event won't fire if the user empties the text field
    serviceLevelNumberField.setRequired( false );
    serviceLevelNumberField.setConvertEmptyInputStringToNull( true );
    serviceLevelNumberField.add( new AjaxFormComponentUpdatingBehavior("onchange") {

      private static final long serialVersionUID = 1L;

      @Override
      protected void onUpdate( AjaxRequestTarget p_target ) {
        String slNumber = getSearchString();
        // works just fine!
        List<String> translationReverseLookupCodes = m_resourceService.reverseLookup( TranslationType.SERVICE_LEVEL_DESCRIPTION, slNumber, getLocale(), null, null );
      }

    });
  }
}

發生故障的組件(ModalWindow中的面板):

public class ChooseServiceLevelPanel extends Panel implements IAjaxIndicatorAware {

  @SpringBean
  protected StringResourceDAO m_resourceService;

  protected void onInitialize() {
   ...

    AjaxSubmitLink searchButton = new AjaxSubmitLink( "searchButton" ) {

      private static final long serialVersionUID = 1L;

      @Override
      public void onSubmit( AjaxRequestTarget p_target, Form<?> p_form ) {
        // once this is called, subsequent page serializations fail!
        List<String> matchingServiceLevelCodes = m_resourceService.reverseLookup( TranslationType.SERVICE_LEVEL_DESCRIPTION, m_descriptionModel.getObject(), getLocale(), null, null );
      }
    };
    searchForm.add( l_searchButton );
}

我可以看到的唯一區別/注意事項是:

  • 失敗者以ajax表單提交(非失敗者不使用表單)
  • 失敗頁面上有2種形式(一種提交搜索參數,另一種選擇搜索結果)
  • 失敗的是ModalWindow內部的面板

有沒有類似的問題?

謝謝

(如果有人遇到類似問題,請發布)

問題是由於ProxyList所致-因為我在DAO類中創建了ProxyList的匿名實現,並且將其返回到標准中,所以這意味着StringResourceDAO也必須進行序列化。

通過用List.stream.filter.collect替換ProxyList,它解決了這個問題。

(盡管我仍然不明白為什么它適用於一個小組而不適用於另一個小組)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM