0

プロジェクトでプライムフェイスを使い始めましたが、すぐに問題が発生しました。エンティティマネージャーを使用してdbから取得したもののリストがあり、それをprimefacesデータテーブルのビューに表示します。私のバッキング Bean には次のものがあります: List getList() ここで、エンティティ マネージャーを使用してデータベースからレコードを取得し、すぐに返します。

および myService:

public List<MyEntity> getDataList(){
  return entityManager.createNamedQuery("MyEntity.getAll").getResultList();
}

私の豆:

public List<MyEntity> getList(){
  return myService.getDataList();
}

景色:

<p:dataTable var="myEntityInstance" value="#{myBean.list}"...

この方法では、primefaces の並べ替えが機能していませんでした。スタックのどこかで、リストがバッキング Bean のメンバーである必要があることを読みましたが、これは奇妙だと思います。サーバーのメモリがオブジェクトをロードし、セッション全体でそれらを維持します。これに加えて、ビューにリクエストを行うたびに手動で行う必要があるため、リストを更新し続けるにははるかに多くのオーバーヘッドがあります。そのページの最初のリクエストが @PostConstruct アノテーション付きメソッドで行われたときに、私のリストが取得されます..その後、最新の状態に保つ必要があります..
リストをデータベースから直接取得してprimefacesに渡し、それをBeanに保持しない他の方法があるかどうかを知る必要がありますか? これまでのところ、primefaces が提供するものには満足していません。デザインは非常に優れていますが、機能には多くのバグがあります。その中の他のコンポーネントにも同様の問題があり、汚い修正を見つけましたが、単純さよりも複雑さが気になります。

4

1 に答える 1

0

編集はさておき、

ここでの問題は、並べ替えるたびにリストがエンティティから更新されることです。並べ替え後に UI が更新されるたびにフレームワークが設定されるため、新しいリストを取得しています。

基本的にあなたが見ている - >(これは正確ではなく、それが何をしているかのスケッチです)

  UI -> sort(myBean.getList());
  UI -> redraw(myBean.getList());

これを見ると、2 つの異なる参照があることを意味します。参照 #1 を並べ替えてから破棄し、レンダリングする新しい参照を取得します。したがって、並べ替えは機能しません。

解決策は、並べ替え後に参照できるメンバーを使用することです。セッションまたはリクエストスコープの代わりにビュースコープを使用できるため、これは大きな問題ではありません。メモリに関しては、それについて考えるのは正しいですが、機能が失われているため、最適化しすぎている可能性があります。

要するに、修正は->

@ViewScoped
public class MyBean
{
  private List<T> myList;
  public List<T> getMyList()
  {
    if(myList != null)
      return myList;
    myList = Service.getMyList();
    return myList;
  }
}

リストをソートして参照を維持できるようになったため、コンポーネントは機能します。実際にメモリの問題が発生した場合は、サービス側で並べ替えを実行する最適化のパスをたどり始めることができます。呼び出しに基づいて並べ替えられた新しいリストを作成し、リクエスト スコープの下よりも戻ります。Primefaces ではそれが可能ですが、最初に簡単な方法を試してください。

//----------- ネタバレに応えて (今日は時間があり、面白いので...)--------/

私はあなたと敵対するつもりはありません。その規模の場合、メモリ負荷に基づいて処理するカスタム コンポーネントを実装しないのはなぜでしょうか? 明らかに、エンティティとデータベース自体の間に抽象化があるため、独自の並べ替えを実装して、getData()メソッドが維持されている参照ではなく、正しい並べ替えられたセットを返すことができるようにします。明らかに、Primefaces (およびほとんどの JSF 実装) は参照 (ステートフル) を維持するため、低メモリ ソリューションが必要になります。

おそらく次のようになります->

@RequestScoped
public class LessMemoryBean
{
  public List<T> getList()
  {
    StatefulBean state = getStatefulBean();
    //Some switch/case or other method of determining state
    return service.getSortedList(state.getState()); //I like hashmaps, but anything could work.
  }
}

@ViewScoped
public class StatefulBean
{
  private HashMap<String, Boolean> state;
  public void sortField(String key, boolean sortBy)
  {
    state.put(key, sortBy); //Construct the proper query via the keys provided
  }
}

//XHTML
<p:dataTable value="#{lessMemoryBean.data}">
  <!-- Whatever you need -->
  <p:column>
    <f:facet name="header">
      <p:commandButton 
        //Do whatever control method you want for sorting and setting booleans
      />
    </f:facet>
  </p:column>
....

RequestScoped Bean への参照を使用しており、その Bean が ViewScoped を参照しているため、リストはリクエストに格納されますが (できるだけ早く破棄されます)、テーブルの状態は分離されます。明らかにそれはそのままではありません.Primefacesはいくつかのリスナーをサポートしていますが、オプションが何であるかを確認するには、さらに深く掘り下げる(RTFM)必要があります. また、これはオープン ソースであるため、単に表を拡張して、Collection.

私の意見では、あなたは最適化について話しています。これは、多くの追加作業を行う必要があることを意味します。やってみてください(個人的には、この状況では標準のデータテーブルを使用するか、独自の複合コンポーネントを実装します。最大で1〜2日はそれほど作業しません)。

于 2012-12-20T19:01:57.500 に答える