<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Se hace camino al andar... &#187; jpa</title>
	<atom:link href="http://blog.jmbeas.es/tag/jpa/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jmbeas.es</link>
	<description>Experiencias de un informático vocacional buscando la calidad y sus efectos colaterales.</description>
	<lastBuildDate>Mon, 16 Jan 2012 07:25:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>

   <image>
    <title>Se hace camino al andar...</title>
    <url>http://0.gravatar.com/avatar/8c024022cec721aaa11dc3b092e2c29c.png?s=48</url>
    <link>http://blog.jmbeas.es</link>
   </image>
		<item>
		<title>Spring, JPA y DBUnit (2)</title>
		<link>http://blog.jmbeas.es/2008/07/08/spring-jpa-y-dbunit-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=spring-jpa-y-dbunit-2</link>
		<comments>http://blog.jmbeas.es/2008/07/08/spring-jpa-y-dbunit-2/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 11:55:00 +0000</pubDate>
		<dc:creator>jmbeas</dc:creator>
				<category><![CDATA[Del viejo blog]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ddd]]></category>
		<category><![CDATA[jpa]]></category>

		<guid isPermaLink="false">http://jmbeas.iexpertos.com/spring-jpa-y-dbunit-2/</guid>
		<description><![CDATA[Vaya, olvidé ayer explicar un detalle interesante (no imprescindible para los que ya conozcáis JPA). Pero creo que lo correcto es completar el artículo y dejarlo &#8220;hecho, hecho&#8221;.Se trata de la clase principal de nuestro dominio en el ejemplo: la entidad User. @Entitypublic class User { @Id String id; @Column(unique=true) private String username; @Column private [...]]]></description>
			<content:encoded><![CDATA[<div xmlns='http://www.w3.org/1999/xhtml'>Vaya, olvidé ayer explicar un detalle interesante (no imprescindible para los que ya conozcáis JPA). Pero creo que lo correcto es completar el artículo y dejarlo &#8220;hecho, hecho&#8221;.<br/><br/>Se trata de la clase principal de nuestro dominio en el ejemplo: la entidad User.<br/>
<pre name="code" class="java"><br/>@Entity<br/>public class User {<br/><br/>    @Id<br/>    String id;<br/>    <br/>    @Column(unique=true)<br/>    private String username;<br/>    <br/>    @Column<br/>    private String name;<br/>    <br/>    @Column<br/>    private String surname;<br/><br/>    public User(String username, String name, String surname) throws UserInitializationException {<br/>        this.username = username;<br/>        this.name = name;<br/>        this.surname = surname;<br/>        if ( username == null ) {<br/>            throw new UserInitializationException("username is null");<br/>        }<br/>        if ( "".equals(username.trim())) {<br/>            throw new UserInitializationException("username is empty");<br/>        }<br/>    }<br/>    <br/>    public String getUsername() {<br/>        return username;<br/>    }<br/><br/>    public String getName() {<br/>        return name;<br/>    }<br/><br/>    public String getSurname() {<br/>        return surname;<br/>    }<br/><br/>    /**<br/>     * Changing someone's name can have side effects.<br/>     * <br/>     * <a href="http://twitter.com/param" class="twitter-user-link" title="param profile on Twitter" target="_blank">@param</a> name<br/>     */<br/>    public void changeName(String name) {<br/>        this.name = name;<br/>    }<br/><br/>    /**<br/>     * Changing someone's surname can have side effects.<br/>     * <br/>     * <a href="http://twitter.com/param" class="twitter-user-link" title="param profile on Twitter" target="_blank">@param</a> surname<br/>     */<br/>    public void changeSurname(String surname) {<br/>        this.surname = surname;<br/>    }<br/><br/>    public String getId() {<br/>        return this.id;<br/>    }<br/>    <br/>    /**<br/>     * Private constructor only for JPA-use. <br/>     */<br/>    private User() {    }<br/><br/><br/>}<br/><br/></pre>
<p><br/><br/>Fijaos en dos detalles que sólo tienen que ver con la persistencia:<br/>
<ul>
<li>El atributo id (anotado convenientemente con <a href="http://twitter.com/Id" class="twitter-user-link" title="Id profile on Twitter" target="_blank">@Id</a> para que el ORM se encargue de generarlo y todo eso) y su correspondiente getter. No tiene nada que ver con el dominio y, por tanto, si fueramos puristas no debería estar en esta clase sino en un DTO especializado. Sin embargo, JPA justamente nos viene a ayudar en esto para evitar esas clases utilitarias que no hacen más que enredarnos&#8230;<br/></li>
<li>El constructor vacío que hemos dejado como privado tampoco tiene nada que ver con el dominio. De hecho, es el ORM el que lo necesita para instanciar las clases a partir de los datos en la BD. Por eso lo he dejado como privado, porque así evitamos la tentación de usar esta clase como DTO.</li>
</ul>
<p>El resto es una clase del dominio: una entidad, tal y como la clasificaría Eric Evans y tal y como la hemos estereotipado con la anotación @Entity.<br/><br/></div>
<div class="blogger-post-footer">http://jmbeas.blogspot.com</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.jmbeas.es/2008/07/08/spring-jpa-y-dbunit-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spring, JPA y DBUnit</title>
		<link>http://blog.jmbeas.es/2008/07/07/spring-jpa-y-dbunit/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=spring-jpa-y-dbunit</link>
		<comments>http://blog.jmbeas.es/2008/07/07/spring-jpa-y-dbunit/#comments</comments>
		<pubDate>Mon, 07 Jul 2008 10:18:00 +0000</pubDate>
		<dc:creator>jmbeas</dc:creator>
				<category><![CDATA[Del viejo blog]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[dbunit]]></category>
		<category><![CDATA[ddd]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://jmbeas.iexpertos.com/spring-jpa-y-dbunit/</guid>
		<description><![CDATA[Como ahora tengo bastante tiempo libre, he empezado una aplicación para prototipar algunos conceptos que me interesa fijar. Así, he comenzado por resolver la arquitectura básica de persistencia. He decidido usar Spring y JPA (Hibernate). Y para las pruebas he querido usar también DbUnit para llenar una base de datos en memoria (H2).Y como estaba [...]]]></description>
			<content:encoded><![CDATA[<div xmlns='http://www.w3.org/1999/xhtml'>Como ahora tengo bastante tiempo libre, he empezado una aplicación para prototipar algunos conceptos que me interesa fijar. Así, he comenzado por resolver la arquitectura básica de persistencia. He decidido usar Spring y JPA (Hibernate). Y para las pruebas he querido usar también DbUnit para llenar una base de datos en memoria (H2).<br/><br/>Y como estaba bastante oxidado, estuve viendo las nuevas anotaciones en Spring 2 y me llamó la atención el estereotipo <a href="http://twitter.com/Repository" class="twitter-user-link" title="Repository profile on Twitter" target="_blank">@Repository</a>. Dado que encaja muy bien con el enfoque de &#8220;modelo rico&#8221; en el que quiero trabajar, he estado jugando con esto y ha quedado así.<br/><br/>Comenzaré por el test.<br/>
<pre class="java" name="code"><br/>@ContextConfiguration(locations = {"classpath:/META-INF/dao-test-context.xml"})<br/>public class UserRepositoryTest extends AbstractRepositoryTest {<br/><br/>  @Autowired<br/>     private UserDAO userDAO;<br/><br/>  @Test<br/>  public void testFindByUsername() {<br/>    User aUser = userDAO.findByUsername("rob");<br/>    assertEquals("0001", aUser.getId());<br/>    assertEquals("Robert", aUser.getName());<br/>    assertEquals("Smith", aUser.getSurname());<br/>  }<br/></pre>
<p><br/><br/>La anotación <a href="http://twitter.com/ContextConfiguration" class="twitter-user-link" title="ContextConfiguration profile on Twitter" target="_blank">@ContextConfiguration</a> permite decir dónde están los ficheros de configuración de Spring (para nuestro ejemplo sólo usamos uno, pero se pueden poner todos los que se quieran). Con <a href="http://twitter.com/Autowired" class="twitter-user-link" title="Autowired profile on Twitter" target="_blank">@Autowired</a> inyectamos el DAO que vamos a probar sin necesidad de declararlo en el xml.<br/><br/>El código de la clase abstracta de la que extendemos tiene la &#8220;fixture&#8221; de la base de datos usando DbUnit.<br/>
<pre class="java" name="code"><br/>@RunWith(SpringJUnit4ClassRunner.class)<br/>@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,TransactionalTestExecutionListener.class})<br/>@Transactional<br/>public class AbstractRepositoryTest {<br/><br/>  private static String TEST_DATA_FILE = "src/test/resources/dbunit-test-data.xml";<br/><br/>  /** Logger available to subclasses */<br/>  protected final Log logger = LogFactory.getLog(getClass());<br/><br/>  @Autowired<br/>  private DataSource dataSource;<br/> <br/>  private DataSource getDataSource() {<br/>    return this.dataSource;<br/>  }<br/> <br/>  @BeforeTransaction<br/>  public void onSetUpInTransaction() throws Exception {<br/>    logger.info("*** Inserting test data ***");<br/>    // Use spring to get the datasource<br/>    DataSource ds = getDataSource();<br/>    Connection conn = ds.getConnection();<br/>     try {<br/>      IDatabaseConnection connection = new DatabaseConnection(conn);<br/>      DatabaseOperation.CLEAN_INSERT.execute(connection,<br/>             new FlatXmlDataSet(new FileInputStream(TEST_DATA_FILE),false));<br/>    } finally {<br/>      DataSourceUtils.releaseConnection(conn, ds);<br/>      logger.info("*** Finished inserting test data ***");<br/>    }<br/>  }<br/> <br/>  @AfterTransaction<br/>  public void onTearDownInTransaction() throws Exception {<br/>    // Delete the data<br/>    DataSource ds = getDataSource();<br/>    Connection conn = ds.getConnection();<br/>    try {<br/>      IDatabaseConnection connection = new DatabaseConnection(conn);<br/>      DatabaseOperation.DELETE.execute(connection, new FlatXmlDataSet(<br/>        new FileInputStream(TEST_DATA_FILE)));<br/>    } finally {<br/>      DataSourceUtils.releaseConnection(conn, ds);<br/>      logger.info("*** Finished removing test data ***");<br/>    }<br/>  }<br/></pre>
<p><br/><br/>El &#8220;truco&#8221; aquí consiste en la anotación <a href="http://twitter.com/Transactional" class="twitter-user-link" title="Transactional profile on Twitter" target="_blank">@Transactional</a> y la inyección de DataSource (que está declarada en el xml de Spring).<br/><br/>El repositorio lo implementamos como un DAO, pero en vez de heredar de JpaDaoSupport (que es quizás lo más común cuando usamos Spring) lo implementamos independiente de Spring (aunque añadamos la anotación @Repository). Cuando usamos <a href="http://twitter.com/Repository" class="twitter-user-link" title="Repository profile on Twitter" target="_blank">@Repository</a>, el contenedor de Spring &#8220;sabe&#8221; cómo inyectar el EntityManager sin que tengamos que decirle nada explícitamente.<br/><br/>
<pre class="java" name="code"><br/>@Repository<br/>public class JpaUserDAO implements UserDAO {<br/><br/> private EntityManager entityManager;<br/>    <br/>    @PersistenceContext<br/>    public void setEntityManager(EntityManager entityManager)   {<br/>  this.entityManager = entityManager;<br/>    }<br/>    <br/> public EntityManager getEntityManager() {<br/>  return entityManager;<br/> }<br/><br/> public User findByUsername(final String username) {<br/>  return (User) getEntityManager().<br/>    createQuery("from User where username = :username").<br/>    setParameter("username", username).<br/>    getSingleResult();<br/> }<br/></pre>
<p><br/><br/><br/><br/>Como es JPA, es necesario el fichero META-INF/persistence.xml.<br/><br/>
<pre class="xml" name="code"><br/>&lt;persistence version="1.0"&gt;<br/>  xmlns="http://java.sun.com/xml/ns/persistence"<br/>  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br/>  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence <br/>    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"&gt;<br/><br/>  &lt;persistence-unit name="ACME_PU-TEST" transaction-type="RESOURCE_LOCAL"&gt;<br/>    &lt;class&gt;acme.core.users.User&lt;/class&gt;<br/>  &lt;/persistence-unit&gt;<br/>    <br/>&lt;/persistence&gt;<br/></pre>
<p><br/><br/>Obsérvese que apenas hay que darle información. <b>Tenemos</b> que explicitar qué <a href="http://twitter.com/Entity" class="twitter-user-link" title="Entity profile on Twitter" target="_blank">@Entity</a> tenemos (podemos hacerlo en un fichero orm.xml, pero por simplicidad lo he dejado dentro). <br/><br/>Y finalmente, el pegamento de todo esto&#8230; el xml de Spring.<br/>
<pre class="xml" name="code"><br/>&lt;beans xmlns="http://www.springframework.org/schema/beans"<br/>  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <br/>  xmlns:context="http://www.springframework.org/schema/context"<br/>  xsi:schemaLocation="http://www.springframework.org/schema/beans<br/>    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd<br/>    http://www.springframework.org/schema/context<br/>    http://www.springframework.org/schema/context/spring-context-2.5.xsd"<br/>  default-autowire="byName"&gt;<br/> <br/>  &lt;context:component-scan base-package="acme.core"/&gt;<br/>  &lt;context:annotation-config/&gt;<br/> <br/>  &lt;bean id="entityManagerFactory" <br/>    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;<br/>     &lt;property name="dataSource" ref="dataSource"/&gt;<br/>     &lt;property name="jpaVendorAdapter"&gt;<br/>        &lt;bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"&gt;<br/>        &lt;property name="databasePlatform" value="org.hibernate.dialect.H2Dialect"/&gt;<br/>        &lt;property name="showSql" value="true"/&gt;<br/>           &lt;property name="generateDdl" value="true"/&gt;<br/>        &lt;/bean&gt;<br/>     &lt;/property&gt;<br/>     &lt;property name="persistenceUnitName" value="ACME_PU-TEST"/&gt;<br/>  &lt;/bean&gt;<br/> <br/>  &lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"<br/>   destroy-method="close"&gt;<br/>    &lt;property name="driverClassName" value="org.h2.Driver"/&gt;<br/>    &lt;property name="url" value="jdbc:h2:mem:test_mem"/&gt;<br/>    &lt;property name="username" value="sa"/&gt;<br/>    &lt;property name="password" value=""/&gt;<br/>  &lt;/bean&gt;<br/> <br/>  &lt;bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"/&gt;<br/><br/>&lt;/beans&gt;<br/></pre>
<p><br/>Es importante señalar que hay dos partes en este xml (de hecho, los he fusionado para que resultara más compacto, pero realmente los tengo separados): los elementos del espacio de nombres &#8220;context&#8221; y &#8220;beans&#8221; respectivamente.<br/><br/>Las primeras son necesarias para poder usar <a href="http://twitter.com/Autowire" class="twitter-user-link" title="Autowire profile on Twitter" target="_blank">@Autowire</a> y otras. Las otras son los únicos tres beans que necesitamos declarar en el xml (porque no son nuestros sino implementaciones que vienen con la librería de Spring).<br/><br/>Es importante declarar los tres y usar esos nombres para aprovechar la inyección automática &#8220;byName&#8221;.<br/><br/>Falta el xml con los datos para que DbUnit cree la tabla y rellene los datos de prueba (nuestra &#8220;fixture&#8221;).<br/>
<pre class="xml" name="code"><br/>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br/>&lt;dataset&gt;<br/>    &lt;user id="0001" username="rob" name="Robert" surname="Smith" /&gt;<br/>    &lt;user id="0002" username="rob2" name="Robert" surname="Jones" /&gt;<br/>    &lt;user id="0003" username="peter" name="Peter" surname="Mullins" /&gt;<br/>&lt;/dataset&gt;<br/></pre>
<p><br/><br/>Espero que os sea útil. A continuación os explicaré cómo implementar una capa de servicios que use este repositorio de datos, con sus pruebas de aceptación (con Concordion, por supuesto) y todo&#8230; <img src='http://blog.jmbeas.es/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </div>
<div class="blogger-post-footer">http://jmbeas.blogspot.com</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.jmbeas.es/2008/07/07/spring-jpa-y-dbunit/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>TS-3559</title>
		<link>http://blog.jmbeas.es/2007/06/11/ts-3559/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ts-3559</link>
		<comments>http://blog.jmbeas.es/2007/06/11/ts-3559/#comments</comments>
		<pubDate>Mon, 11 Jun 2007 22:26:00 +0000</pubDate>
		<dc:creator>jmbeas</dc:creator>
				<category><![CDATA[Del viejo blog]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[javaone]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[soa]]></category>

		<guid isPermaLink="false">http://jmbeas.iexpertos.com/ts-3559/</guid>
		<description><![CDATA[Este fin de semana, mi colega Stephane me ha enseñado la presentación que Adam Bien ha expuesto en la última JavaOne titulada (ahí va el título) :Java 6 Platform, Java DB, Swing, JNLP / Java Web Start, Java Persistence API (JPA) / Enterprise JavaBeans (EJB) 3 : The New &#8220;Operating System&#8221; for Rich Internet Applications. [...]]]></description>
			<content:encoded><![CDATA[<div xmlns='http://www.w3.org/1999/xhtml'>Este fin de semana, mi colega Stephane me ha enseñado la presentación que <a href='http://www.adam-bien.com/'>Adam Bien</a> ha expuesto en la última JavaOne titulada (ahí va el título) :<br /><a href='http://developers.sun.com/learning/javaoneonline/2007/pdf/TS-3559.pdf'><b>Java 6 Platform, Java DB, Swing, JNLP / Java Web Start, Java Persistence API (JPA) / Enterprise JavaBeans (EJB) 3 : The New &#8220;Operating System&#8221; for Rich Internet Applications</b></a>.</p>
<p>En esta presentación, el autor (que es un miembro de la comunidad de <a href='https://java-champions.dev.java.net/'>Java Champions</a>) explica una arquitectura para aplicaciones basada en los siguientes principios:<br /></br>
<ul>
<li>Domain Driven Design (Diseño guiado por el dominio): se refiere a que los objetos que modelan el negocio (<a href='http://www.corej2eepatterns.com/Patterns2ndEd/BusinessObject.htm'>patrón Business Object</a>) representan el estado del negocio e incluye cierto comportamiento (auto-validaciones, manejo de relaciones con otros objetos de dominio dependientes, <a href='http://es.wikipedia.org/wiki/CRUD'>CRUD</a>). No sé si tiene algo que ver con los libros de igual título (&#8220;<a href='http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215'>Domain-Driven Design</a>&#8221; y &#8220;<a href='http://www.amazon.com/Applying-Domain-Driven-Design-Patterns-Examples/dp/0321268202'>Applying Domain-Driven Design and Patterns</a>&#8220;).</li>
<li>Implementación de los objetos de dominio como entidades <a href='http://java.sun.com/javaee/overview/faq/persistence.jsp'>JPA</a>.</li>
<li>Otra lógica más allá de la que un objeto de dominio sea capaz de resolver por si mismo se debe implementar como una fachada (POJOs o stateless/stateful session beans). Estamos hablando del acceso al EntityManager de JPA, de la transaccionalidad, seguridad, trazas de auditoría&#8230;</li>
<li>No se usan DTOs (<a href='http://www.corej2eepatterns.com/Patterns2ndEd/TransferObject.htm'>patrón Transfer Object</a>) sino que los objetos de dominio viajan desde la capa de negocio hasta la capa de presentación sin el sobrecoste de las transformaciones o las copias de valores.</li>
</ul>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_QhcG1I9XuzE/Rm3NFidOVaI/AAAAAAAAAAs/GIDScW7DgoY/s1600-h/DomainDrivenDesign.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp3.blogger.com/_QhcG1I9XuzE/Rm3NFidOVaI/AAAAAAAAAAs/GIDScW7DgoY/s400/DomainDrivenDesign.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5074937850148836770" /></a><br />La diapositiva 18 es especialmente clarificadora. Sin embargo, <a href='http://www.adam-bien.com/roller/page/abien?entry=update_my_javaone_session_ts'>le he preguntado directamente a Adam Bien</a> cómo encaja esta propuesta en una arquitectura orientada a servicios (SOA). Su respuesta ha sido que los servicios deben implementar lógica no relacionada con los objetos de dominio, mientras que las fachadas (o gateways, implementadas como <a href='http://acronyms.thefreedictionary.com/SFSB'>SFSB</a>) se encargan de lógica independiente de la instancia (como el CRUD) y exponen directamente entidades JPA (los objetos de dominio), que se almacenan localmente.<br /></br><br /></br>Me queda pendiente preguntarle cómo resolveríamos los problemas de concurrencia que provocaría un webservice que modificara registros en la base de datos que, a su vez, correspondieran a objetos de dominio presentes en la sesión de una de esas SFSB.<br /></br></div>
<div class="blogger-post-footer">http://jmbeas.blogspot.com</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.jmbeas.es/2007/06/11/ts-3559/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

