Tuesday, December 15, 2015

ADF LOV with Sub-Query parameter

Pada ADF biasanya sebuah LOV (List Of Value) berasal dari sebuah VO (View Object).
Apabila sebuah LOV memiliki dependensi parameter dari field lainnya pada UI, maka biasanya query pada VO nya akan memiliki :param.

Misalnya seperti berikut:
select distinct xx.kolom_1, xx.kolom_2
from table_xx xx, (
    select kolom_a, kolom_b
    from table
    where kolom_c = :param1
) yy
where 
xx.kolom_3 = yy.kolom_a
yy.kolom_b = :param2 

pada umumnya untuk menghandle masalah depedensi ini kita akan menggunakan view criteria atau bindParameter.

Cara kerja dari view criteria adalah membungkus query vo dan menambahkan where clause menjadi seperti berikut:

select * from (
    select distinct xx.kolom_1, xx.kolom_2
    from table_xx xx, (
        select kolom_a, kolom_b
        from table
        where kolom_c = :param1
    ) yy
    where 
    xx.kolom_3 = yy.kolom_a
    yy.kolom_b = :param2
    )
where ....
 
dan sebuah viewcriteria membutuhkan query yang memiliki kolom yang akan menjadi filter.
jadi untuk query yang menggunakan distinct akan bermasalah, karena mungkin saja kolom yang akan menjadi filter tersebut mempengaruhi jumah data hasil query

select * from (
    select distinct xx.kolom_1, xx.kolom_2, yy.kolom_b
    from table_xx xx, (
        select kolom_a, kolom_b
        from table
        where kolom_c = :param1
    ) yy
    where 
    xx.kolom_3 = yy.kolom_a
    yy.kolom_b = :param2
    )
where kolom_b = :parameter

Tidak hanya untuk query DISTINCT saja, karena ada beberapa sql lainnya yang tidak bisa dibungkus oleh where clause contohnya seperti START WITH dan CONNECT BY 

Sedangkan bind parameter untuk parameter pada where clause itu sejauh yang saya coba tidak bisa di implement pada sebuah LOV dengan VO yang memiliki query seperti diatas.

Lalu apa bagaimana caranya?
VO di ADF kan hanya bisa menggunakan viewcriteria dan bind parameter untuk mengisi parameter pada query?

Setelah bertukar pikiran dalam diskusi masalah ini, akhirnya di temukan sebuah trik untuk menyelesaikan masalah ini.
Yaitu dengan mengganti query dari VO tersebut secara programmatic pada saat pop-up dialog LOV muncul, atau dengan kata lain adalah meng-harcode parameter kedalam query tersebut.

berikut gambarannya :

select distinct xx.kolom_1, xx.kolom_2
from table_xx xx, (
    select kolom_a, kolom_b
    from table
    where kolom_c = 'ABCDEF'
) yy
where 
xx.kolom_3 = yy.kolom_a
yy.kolom_b = 'GHIJK' 


Oke diatas adalah overview dari apa yang akan di jelaskan secara detail selanjutnya.

Pertama-tama akan saya berikan contoh untuk mengganti query dari sebuah VO.
Pada contoh berikut query VO diganti didalam sebuah method di dalam ViewObjectImpl

public class VoTableSearchImpl {
  /**
   * This is the default constructor (do not remove).
   */
  public VoTableSearchImpl() {
  }

  public void execSearchQuery(String param1, String param2) {
   
    setFullSqlMode(FULLSQL_MODE_AUGMENTATION); 
    setQuery("select distinct xx.kolom_1, xx.kolom_2
            from table_xx xx, (
                select kolom_a, kolom_b
                from table
                where kolom_c = '"+ param1 +"'
            ) yy
            where 
            xx.kolom_3 = yy.kolom_a
            yy.kolom_b = "+ param2 +"'");
    executeQuery();
  }

}

yang perlu diperhatikan adalah semua nama kolom, jumlah kolom, dan type data nya harus sama antara query awal dengan query yang baru


selanjutnya adalah mengimplementasikannya kedalam sebuah LOV

akan ditaruh dalam sebuah method listener pada LOV yaitu launchPopupListener
dan ada satu method tambahan yang diperlukan untuk bisa mendapatkan VO dari suatu LOV

private ViewObject getLovVo(String attributeBinding) {
        BindingContext bctx = BindingContext.getCurrent();
        BindingContainer bindings = bctx.getCurrentBindingsEntry();
        FacesCtrlLOVBinding lov = (FacesCtrlLOVBinding)bindings.get(attributeBinding);
        return lov.getListIterBinding().getViewObject();
    }

dan berikut adalah isi dari method launchPopupListener

public void onLaunchLovNama(LaunchPopupEvent launchPopupEvent) {
    String param1 = (String)getAttrBinding("param1").getAttributeValue();
    String param2 = (String)getAttrBinding("param2").getAttributeValue();
   
    VoTableSearchImpl vo = (VoTableSearchImpl)getLovVo("lovNama");           
    vo.setFullSqlMode(VoTableSearchImpl.FULLSQL_MODE_AUGMENTATION);
    vo.setQuery("select distinct xx.kolom_1, xx.kolom_2
            from table_xx xx, (
                select kolom_a, kolom_b
                from table
                where kolom_c = '"+ param1 +"'
            ) yy
            where 
            xx.kolom_3 = yy.kolom_a
            yy.kolom_b = "+ param2 +"'");
    vo.executeQuery();
}

Sekian dulu dan selamat mencoba.

No comments:

Post a Comment