martes, 14 de septiembre de 2010

Enmulando EJB en Web usando Spring

Cuando salió el EJB 3.1 con la capacidad de poderse ejecutar en un módulo web, comencé a usarlo sin parar. Con los EJB me hace más fácil conectarme a la base de datosusando JPA porque simplemente debería usar  @PersistenceContext respectivamente.

Pero no todos los servidores  donde uno va a desplegar aplicaciones son Java EE6, así que las facilidades del EJB 3.1 serían truncadas.

Afortunadamente existe Spring para ayudarnos a instanciar clases como si fueran EJB, y más aún, nos permite usar JPA y mantener las notaciones  @PersistenceContext.

Veamos cómo se hace esto.

Para comenzar, debemos considerar que existe nuestro archivo persistence.xml con la conexión a la base de datos. Para este ejemplo estoy usan la base de datos sample que viene en el JavaDB.


<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" 
   xmlns="http://java.sun.com/xml/ns/persistence" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
                       http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="EjbSpringWebPU" transaction-type="JTA">
    <jta-data-source>jdbc/sample</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties/>
  </persistence-unit>
</persistence>

Nuestros "Facade" que funcionarán como los EJB, será casi como un EJB, con todo la notación de persistencia:


public class DiscountCodeFacade {

    @PersistenceContext(unitName = "EjbSpringWebPU")
    private EntityManager em;

    public List<DiscountCode> getDiscountCodes() {
        Query query = em.createQuery("select o from DiscountCode o");
        return query.getResultList();
    }
}

Hasta aquí, todo normal. Ahora, necesitamos instanciar este facade y que ya tenga la conexión a la persistencia. Bueno, en Spring se tiene que hacer esto:

Instanciar la persistencia:

    <bean id="EjbSpringWebPU" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="EjbSpringWebPU"/>
    </bean>

Luego, decirle que ejecute todas las notaciones que se solicitarán en las siguientes clases:

    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

Para terminar, instanciar el Facade:

    <bean id="DiscountCodeFacade" class="service.DiscountCodeFacade" />

Y listo, ya se puede utilizar casi como un EJB:

DiscountCodeFacade facade=ServiceFactory.getInstance().getDiscountCodeFacade();
List<DiscountCode> discountCodes = facade.getDiscountCodes();

El proyecto utilizado para este post se encuentra aquí:

https://java.net/downloads/apuntes/samples/web/EjbSpringWeb.tar.gz