2017-07-04 8 views
1

ページに表示されるデータテーブルの階層があります。CDI:特定のタイプのエンティティ(データテーブル階層)の選択/非選択の観察

上部に選択できる項目はCashValueCalculationです。 1つを選択すると、選択可能なPaymentstreamエンティティの別のデータテーブルがその下に表示されます。さらに3回目に、その種類のエンティティを選択すると、Paymentエンティティの最後のデータテーブルが表示されます。

このため3つのCDI豆があります。CashValueCalculationManagerPaymentStreamManagerPaymentManagerは、階層構造を形成する、:

`CashValueCalculationManager` 
    | 
    +- `PaymentstreamManager` 
     | 
     +- `PaymentstreamManager` 

これらのBeanが実際に行わ選択/非選択イベント(UI上でその Beanに反応するようになっていますもちろん、JSFを使用してPrimeFaces p:dataTableを介して)。

各Beanは、エンティティのPKとエンティティクラス自体を汎用として持つフレームワーククラスから継承します。ここではいくつかの関連するコードは次のとおりです。

public abstract class BaseManager<K, T extends Entity<K>> extends BaseCdiViewBean implements Manager<K, T> 
{ 
    private static final long serialVersionUID = 1L; 

    private List<T> entities; 

    private T selectedEntity; 
    private EMode mode; // VIEW, ADD, EDIT, REMOVE 

    // CDI event producers 

    @Inject 
    @SingleSelect 
    private Event<T> selectEvent; 

    @Inject 
    @SingleUnselect 
    private Event<T> unselectEvent; 

    ... 

    @Override 
    public void setSelectedEntity(T selectedEntity) 
    { 
     if (selectedEntity == null) 
     { 
      // null entity not really selectable, interpret as clear selection command 
      this.setSelectedEntity(null); 

      // fire CDI event to 0-n observers 
      this.unselectEvent.fire(this.newEntity()); // cannot pass null to CDI events, use a new entity created from a concrete bean 
      return; 
     } 

     // here we have a non-null selected entity 
     this.selectedEntity = selectedEntity; 

     // fire CDI event to 0-n observers 
     this.selectEvent.fire(selectedEntity); 
    } 

    ... 
} 

Entityインターフェースはちょうどです:

public interface Entity<K> 
{ 
    public K getPk(); 
    public void setPk(K pk); 
} 

親のマネージャーCashValueCalculationManagerPaymentStreamManagerにオブザーバーとしてBaseSubManagerと行為から2人のサブマネージャーPaymentStreamManagerPaymentManager継承それぞれ(それは何彼らはそうしている):

public abstract class BaseSubManager<K, T extends Entity<K>, P extends Entity<?>> extends BaseManager<K, T> implements SubManager<K, T, P> 
{ 
    private static final long serialVersionUID = 1L; 

    private P parentEntity; 

    @Override 
    public P getParentEntity() 
    { 
     return this.parentEntity; 
    } 

    @Override 
    public void setParentEntity(P parentEntity) 
    { 
     this.parentEntity = parentEntity; 
    } 

    public void onSelect(@Observes @SingleSelect P selectedParentEntity) 
    { 
     System.out.println(this.getClass().getSimpleName() + ": selected parent entity: " + selectedParentEntity); 
     this.setParentEntity(selectedParentEntity); 
    } 

    public void onUnselect(@Observes @SingleUnselect P unselectedParentEntity) 
    { 
     System.out.println(this.getClass().getSimpleName() + ": unselected parent entity: " + unselectedParentEntity); 
     this.setParentEntity(null); 
    } 
} 

@SingleSelect注釈:

@Qualifier 
@Retention(RUNTIME) 
@Target({FIELD, PARAMETER}) 
public @interface SingleSelect 
{ 
    // no additional interface 
} 

@SingleUnselectは注釈:

@Qualifier 
@Retention(RUNTIME) 
@Target({FIELD, PARAMETER}) 
public @interface SingleUnselect 
{ 
    // no additional interface 
} 

私が今欲しい何がPaymentstreamManagerCashValueCalculationManagerPaymentManagerPaymentstreamManagerのみからイベントを受信からイベントを受信することです。

しかし、毎回私はトップレベルのマネージャーCashValueCalculationManagerのエンティティを選択し、両方のサブマネージャ@Observer方法は、(私は必要なものではないれ、そしてもちろんのメソッド呼び出し)イベントを受け取る:選択で

テスト:非選択テストで

21:17:34,310 INFO [stdout] PaymentManager: selected parent entity: CashValueCalculation[pk=2] 
21:17:34,312 INFO [stdout] PaymentStreamManager: selected parent entity: CashValueCalculation[pk=2] 

21:19:20,176 INFO [stdout] PaymentStreamManager: unselected parent entity: CashValueCalculation[pk=null] 
21:19:20,177 INFO [stdout] PaymentManager: unselected parent entity: CashValueCalculation[pk=null] 

Q

なぜこれはすぐに動作しないのですか?動作させるにはコードを変更する必要がありますか?

おかげ

答えて

1

推測:

ジェネリック医薬品は、型消去を経由して実装されているとして、あなたは基本的には、実行時にBaseManagerに次のイベントがあります。一方、

@Inject 
@SingleSelect 
private Event<Object> selectEvent; 

@Inject 
@SingleUnselect 
private Event<Object> unselectEvent; 

、あなたは観察します次のようになります。

public void onSelect(@Observes @SingleSelect Object selectedParentEntity) 
public void onUnselect(@Observes @SingleUnselect Object unselectedParentEntity) 

...これは明らかに一致しますすべてのイベント。私は、IS試す修飾子の注釈にクラス値を追加し、のようなものだろうと何

@Qualifier 
@Retention(RUNTIME) 
@Target({FIELD, PARAMETER}) 
public @interface SingleSelect 
{ 
    public Class<?> value(); 
} 

@Inject 
@SingleSelect(SomeConcreteType.class) 
private Event<Object> selectEvent; 

public void onSelect(@Observes @SingleSelect(SomeConcreteType.class) P selectedParentEntity) 

この方法で、あなたのコンテナは、実行時にさまざまなイベントを区別することができるはずです。

+0

妥当と思われます。ありがとう。私は来週、これをもう少し詳しく見ていきます... – Kawu

関連する問題