Prosinec 23rd, 2008JPA 2.0

Nedávno zveřejněná specifikace JPA 2.0 obsahuje asi nejzásadnější posun v možnosti psaní Criteria API. Pokud někdo očekává okopírované Criteria API z Hibernate bude možná trošku zklamán (či potěšen).

Nový způsob je totiž více postaven na „objektovosti“ daných entit. Dobrý zdroj a ukázku lze najít na blogu Gavina Kinga.

Osobně toto považuji za správný krok. Samotné JPA (EntityManager) umí pouze JPQL dotazy, které jsou napsané jako jeden String řetězec. To sebou přináší hromadu nevýhod a v mnoha případech nutí, aby si vývojář napsal nějaký ten vlastní „JPQL String Parser“. Z tohoto důvodu jsem osobně JPA degradoval na „pouhé“ ORM mapovaní, kde mi jasně specifikovaný standard umožňuje být více nezavislý na použitém „provideru pro persistenci“. EntityManager jsem vyměnil za „Hibernate Session“ a vesele si psal svá Criteria API.

Hibernate Criteria API ovšem nejsou všespásná. V některých případech je tento způsob nepoužitelný. Občas člověk narazí na nějaký ten bug či extrémní složitost psaní dotazu. Jakmile vznikne požadavek na „subquery“, je Hibernate Criteria API velká loterie. Samotná podpora poddotazů je totiž žalostná. Podle toho, co jsem zatím viděl, si myslím, že způsob zápisu v JPA 2.0 bude v tomto více přizpůsobivější a umožní plně nahradit jakýkoli JPQL dotaz.

Další věcí je návratová hodnota dotazu. Asi nikdo nepředpokládá, že lze pomocí namapovaných entit vše vyřešit. V takových chvílích nastupují DTO objekty, které se časem začnou množit. Způsob, jak výsledek převádět do vlastních objektů, je v JPA 1.0 dost špatně navržen. Psát „new cela.pakaz.az­.k.ZakaznikDTO(a, zde, hromada, parametru)“ je otřesné. Když k tomu ještě připočítám nutnost tvorby konstruktorů, tak jak jsou tvořeny v JPQL, dostanete se do situace, kdy Vám Java jako staticky typovaný jazyk přestane pomáhat. Budete se muset spoléhat na správnost daných JPQL dotazů i v případech refactoringu (samozřejmě testy mohou pomoci :)).

Proto i zde jsem zvolil Hibernate Criteria API, jelikož způsob návratové hodnoty lze mnohem lépe zapsat pomocí „Hibernate Projections“.

Bohužel i tato volba není úplně ideální a opět obsahuje „mouchy“. První z nich je asi to, že nelze vytvořit DTO objekt, který bude obsahovat referenci na jiný objekt než ten, který zná Hibernate nad JDBC (String, Integer, atd.). Zde se jaksi ztrácí ono magické OOP a nastupuje hromada primitivních DTO objektů, které mezi sebou nelze propojit jako v případě mapovaných entit. Jediné propojení lze samotřejmě provést pouze na úrovni vlastního Java kódu.

I když jsem novou specifikaci nečetl řádek po řádku, nenalezl jsem v této oblasti žádný posun. Je pravdou, že i „select statement“ byl z části vylepšen, ale nikoli tak, aby umožňoval tvorbu vzájemně propojených DTO objektů.

Ale i přesto musím říct, že nové Criteria Query API se mi v JPA dost zamlouvají. Snad bude tento nový způsob zápisu alespoň schopen nahradit Hibernate Criteria API.

Specifikace pro JPA je dosti rozsáhlá a myslím, že jako čtivo na dlouhé zimní večery bude jistě dobrou volbou :)

Minule jsem psal o možnosti spojení Wicketu s EJB3 a o Wicket Security. Dnes se podívám na další vlastnosti a možnosti tohoto webového frameworku.

IBehavior

Jedná se o interface, který je označován jako druh pluginu wicket komponent. Já jsem dané řešení využil například pro statistiku návštěvnosti či pro zjistění, jak dlouho trvalo vyrendrování wicket stránky.

Příklad, pro zjištění doby trvání vyrendrování wicket stránky:
public class TimeBehavior extends AbstractBehavior {
  private long start;

  @Override
  public void beforeRender(Com­ponent component) {
    start = System.curren­tTimeMillis();
  }

  @Override
  public void onRendered(Com­ponent component) {
    super.onRende­red(component);
    long dobaBehu = System.curren­tTimeMillis() – start;
    // dalsi zpracovani
  }
 }

Třída je potomkem AbstractBehavior, což je adaptér pro interface IBehavior. Tuto implementaci stačí poté přiřadit v „BasePage“ (základní Wicket Page, která je předkem všech Page). Samozřejmě, pro Wicket je Page komponenta stejně jako např. TextField. Proto je možné daný plugin přiřazovat i daným komponentám uvnitř Page, Panel, atd.

Možností, jak využít toto rozšíření pro komponenty je mnoho. Pomocí této vlastnosti se například dá z klasického input fieldu vytvořit zadávací políčko s kalendářem pro datum, atd. Stačí implementovat metodu „onComponentTag“ a tu patřičně upravit. Tato funkcionalita s kalendářem je již přímo implementována (viz. wicket-datetime: DatePicker).

Tabulky

Každý webový intranetový systém se z velké části točí okolo poskytování dat v jasně specifikované formě. Nebo chcete-li: „hromada tabulek s vlastní filtrací“. K tomuto účelu poskytuje Wicket přímo vlastní komponenty, viz: repeater example.

Do nedávné doby existoval web: inmethod.com, který danou funkcionalitu rozšiřoval o vlastní druh tabulek. Tato implementace byla zatím asi to nejlepší, co jsem v oblasti webu a webových frameworků viděl.

Tabulky mají statické sloupce a posuvný obsah (ala excel), možnost řazení sloupců, přesun sloupců, změnu velikosti sloupců, atd.

Příliš nechápu proč, byl tento projekt ukončen (zřejmě jako ostatní: nedostatek volného času). Naštěstí je ale možné si přes svn stáhnout zdrojové kódy, které lze použít. Je k dispozicii živá ukázka.

Daný projekt je psán vůči verzi 1.2. Pro verzi 1.3.x není k dispozici alternativa. Osobně danou knihovnu pro verzi 1.3.3 využívám, ovšem s tím, že jsem dané zdrojové kódy musel částečně upravit. Pokud by měl někdo zájem, mohu mu upravenou knihovnu zaslat.

Danou implementaci lze samozřejmě dále rozšiřovat. Stačí se například podívat jak je definována třída: „com.inmethod­.grid.column.Pro­pertyColumn“.

Příště ukáži, jak lze snadno tvořit znovupoužitelné komponenty v Apache Wicket.

Září 19th, 2008Trocha dávky Apache Wicket

Od posledního příspěvku na tomto blogu již uplynula nějaká ta doba. Nebudu tvrdit, že jsem neměl čas. Důvodem byla spíše chuť něco nového napsat. To je ovšem pryč, takže se vrátím zpět ke svému psaní :)

Apache Wicket je zajímavý hned z několika důvodů. Některé z nich jsem prezentoval minule a proto dnes přidám snad jediný důvod: baví mě v něm psát aplikace.

Každý, kdo má alespoň obecnou znalost tohoto frameworku, musí si daný způsob ihned spojit s psaním aplikací ve swingu. Asi bych to vyjádřil slovy: piš to jako ve swingu a přidej k dané třídě html soubor.

Wicket a EJB3

Dají se tyto dvě technologie jednoduše spojit? Repektive dá se snadno zařídit závislost wicket komponenty na EJB servisní beaně? Ano dá. Stačí stáhnout wicket-contrib-javaee.

Pro schopnost provést jednoduché DI (dependency injection) přes anotaci @EJB je třeba definovat referenci ve web.xml.
<ejb-local-ref>
  <ejb-ref-name>cz.irmin­sul.javaee.ej­b3.ServiceLocal</ejb-ref-name>
 <ejb-ref-type>Session</ejb-ref-type>
 <local>cz.ir­minsul.javaee­.ejb3.Service­Local</local>
</ejb-local-ref>
Při definici ejb-ref-name používám celý název daného rozhraní. Důvod je ten, že poté nění třeba při definici DI uvádět @EJB(name=„re­ference“). Výsledné DI vypadá následovně:
public class MyPage extends Page {
 @EJB
 private ServiceLocal service;
 …
 }



Wicket a Security

Existuje několik možností, jak definovat security. Já osobně jsem zvolil WASP. Toto řešení je postaveno na rolích (i když spíše záleží na způsobu implementace). Je zde několik důležitých kroků k uspěšnému nasazení.

  1. Definovat vlastní .hive soubor
  2. Base page musí být potomkem SecureWebPage
  3. Wicket Session musí být potomkem WaspSession
  4. Application class musí být částečně upravena (viz příklady na daném WASP webu)
  5. Musí se definovat vlastní LoginContext a Principal

Nebudu zde rozepisovat jednotlivé kroky. Dané příklady lze najít na odkazovaném webu pro WASP. Uvedu jen to zajímavé:

Definice oprávnění lze použít jak na celou page, tak na danou akci, tak na daný model. Z toho lze usoudit, že daný způsob by měl být dostačující k danému použití v jakémkoli scénáři. Celá tato definice je uvedena v .hive souboru, který je poté nastaven v Application class. Samozřejmě daných .hive souborů může existovat klidně více.

U definice oprávnění v .hive souboru lze nastavit, zda se bude daná definice týkat i potomků daných page tříd. Zda je k nějaké page přístup globální, či pro danou roli, atd.

Daný způsob implementace se mi vcelku zamlouvá. Jediné, co bych danému řešení vytkl je to, že dokumentace je téměř nulová. Jediný zdroj informací jsou proto jen příklady, které si lze stáhnout a poté prozkoumat jejich kód.

Tak to by bylo asi vše. Příště ukáži jak lze využít IBehavior či jak je na tom Wicket s nenáviděnými html tabulkami.


© 2007 finc weblog | iKon Wordpress Theme by Windows Vista Administration | Powered by Wordpress