pátek 18. února 2005

Jednoduší život s EJB

Ani ne před měsícem jsme s JiPim řešili otázku vhodné architektury jednoho webového projektu. V podstatě bylo rozhodnuto, že pro ORM použijeme Hibernate, spor jsme vedli o zbylou část systému. Volba ležela mezi čistokrevnou EJB implementací a nebo POJO like implementaci za použití Springu.

Pohyb v teoretické rovině ani jednoho z nás neuspokojil, domluvili jsme se, že uděláme jednoduchý příkladek (má implementace) převodu částky z jednoho účtu na druhý. Nakonec padlo rozhodnutí na využití Springu. Jedna věc mi ovšem vrtala hlavou a to obdoba statefull bean, které jsem neuměl obecně vyřešit. Dneska jsem s jásotem narazil na článek Spring and EJB Roba Harropa a Jana Machacka (nebude to krajan?), který je zároveň vnadidlem na jejich knihu Pro Spring.

V článku je velice pěkně popsáno využití možností Springu k zjednodušení práce s EJB. Opravdu se mi ten článek líbí a začal jsem uvažovat nad tím, že bychom mohli nakonec EJB v symbióze se Springem použít. Moje úvahy dostaly trhlinu, když jsem si pročítal diskusi na TSS, kde oprávněně He Yu konstatuje I think the article hava a bug for statefull session bean implemention, because the BeanFactory have no any session management for beans it managed. After ejbPassivate all the state will not be restored. Docela mě to zarazilo, ja osobně bych řekl, že ten service je serializovatelný proto je možné udržet stav, ale ruku do ohně bych za to nedal.

středa 16. února 2005

ORM pomocí iBatis SQLMaps

Tématikou ORM (Object Relational Mapping) jsem se na Dagblogu již zabýval ve spotu ORM letem světem. Ten spot je datován do doby, kdy jsme s ORM hodně experimentovali a hledali jsme nejvhodnější nástroj, vítězem se celkem oprávněně stal Hibernate. Při přechodu z klasického SQL na mezivrstvu v podobě ORM jsme narazili hned na několik problémů.

Velkým problémem se ukázalo mapování objektů na stávající databázový model, největší příkoří působily složené klíče. Celkově vzato se mi jako lepší jeví přístup právě opačný, namodelovat relace pomoci objektů a na jeho základě si nechat vygenerovat databázový model.

Když jsem upozorňoval spotem Kdy použít EJB? na zajímavé názory ohledně alternativy k EJB, tak jsem nezabíhal do hloubky jednotlivých témat, která zazněla. Mimochodem jsem tam právě tyto nevýhody Hibernate, alespoň z mého pohledu, zmiňoval. V diskusi se tenkrát objevil tip na alternativu v podobě iBatis SQLMaps.

Pokud jste o iBatis SQLMaps nikdy neslyšeli, můžete si přečíst velice pěkný článek Sunil Patila Object-Relational Mapping with SQLMaps. Mě osobně se iBatis SQLMaps velice líbí a to z toho důvodu, že pro vlastní mapování použijete klasické SQL. Pro některé případy, to je z mého pohledu právě existující velice složité DB schéma, mi SQLMaps připadá jako vhodnější kandidát.

Mimochodem deset důvodů proč používat iBATIS SQL Maps, které jsou na oficiálních stránkách projektu.

  • 10 Works with any database that has a JDBC driver (no plugins required)
  • 9 Configurable caching (including dependencies)
  • 8 Local and Global transaction support and management (JTA)
  • 7 Simple XML mapping document structure
  • 6 Supports Map, Collection, List and Primitive Wrappers (Integer, String etc.)
  • 5 Supports JavaBeans classes (get/set methods)
  • 4 Supports complex object mappings (populating lists, complex object models etc.)
  • 3 Object models are never perfect (no changes required!)
  • 2 Database designs are never perfect (no changes required!)
  • 1 You already know SQL, why waste time learning something else?

Ten jedenáctý a pro mě důležitý představuje podpora ve Spring frameworku.

úterý 15. února 2005

EJB 3.0, Interceptory a Spring

Se zájmem jsem si včera přečetl noticku Pavla Kolesnikova o Druhý Early Draft EJB 3.0. Sice jsem se tím nechtěl vůbec zaobírat, ale stejně jsem neodolal a začetl jsem se do diskuse na TSS. Rozhořela se tam pro mě zajímavá diskuse Annotation vs. XML config, ale to budu komentovat příště. Není žádnou novinkou, že JBoss v oblasti EJB 3.0 nezahálí a poskytuje velice rychle EJB 3.0 preview, jak někdo poznamenal JSR 220 je JBoss camp.

Dneska se na TSS objevil spot JBoss EJB 3.0 Preview 3 Is Out, který mě nahlodal a já jsme neodolal zběžně jsem nakouknul do tutorialu. Aniž bych zkoumal specifikaci, zaujaly mě interceptory. Teď si vypůjčím slova Pavla Kolesnikova

interceptory (uživatelé aplikačního serveru JBoss či přiznivci AOP jistě tuší): interceptor je buď metoda, která se "vsune" do volání business metody nebo třída, jejíž metody fungují interceptor dané třídy (danou třídou je myšlena pouze session či message driven EJB komponenta)

Ve vzpomínaném tutoriálu je interceptorům věnována solidní část, která jejich význam celkem demonstuje. Mě osobně přijdou Interceptory jako příjemné sblížení s AOP. Na druhou si neodpustím malé rýpnutí, tohle máme zavedené a používáme v aplikačním frameworku Spring díky AOP již dávno. Je libo malou ukázku?

Interceptor

 
package my;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class TracingInterceptor implements MethodInterceptor{    
   
  public Object invoke(MethodInvocation invocation) throws Throwable { 
   long start = System.currentTimeMillis();
   try{
      invocation.proceed();
   }finally{
      long time = System.currentTimeMillis() - start;     
      System.out.println("Invocation time: "+ time + "ms");
   }
  }  
}
 

Takto definovaný interceptor, v podstatě aspekt, si dáme do application context (konfigurace Springu).

 
   <bean id="tracingInterceptor" class="my.TracingInterceptor" />  
 

Advisor

Proto abychom mohli tento Interceptor použít, musíme ještě definovat tzv. Advisor, který určuje jestli se daný interceptor použije či nikoliv. Řekněme, že chceme náš interceptor napojit na metodu getFoo, využijeme jeden ze standardních Advisorů, které jsou ve Springu k dispozici. Opět konfigurace v application context.

 
 <bean id="myAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
  <constructor-arg><ref local="tracingInterceptor"/></constructor-arg>
  <property name="mappedNames">
   <list>
    <value>getFoo</value>    
   </list>
  </property>  
 </bean>
 

Napojení Intercetporu na konkrétní třídu

No a nyní, opět deklarativně, napojíme interceptor na vybraný objekt, v našem případě objekt Foo.

 
<bean id="myFooTarget" class="my.Foo" /> 

<bean id="myFoo" class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="proxyInterfaces"><value>my.IFoo</value></property>
  <property name="target"><ref local="myFooTarget"/></property>
  <property name="interceptorNames">
   <list>
    <value>myAdvisor</value>
   </list>
  </property>
</bean> 
 

Pro dokresleni vlastní objekt Foo včetně rozhraní.

 
 package my;
 public interface IFoo{
 public Object getFoo();
 } 
 
 
 package my;
 public class Foo implements IFoo{
  public Object getFoo(){
  //do something
  }
 }
 

Kde miluje anotace více než deklarativní XML, může je využít viz Spring Source Level Metadata Support.