<?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>Yo en el Universo &#187; java</title>
	<atom:link href="http://sixservix.com/blog/david/category/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://sixservix.com/blog/david</link>
	<description>El blog de David Bonilla</description>
	<lastBuildDate>Thu, 09 Sep 2010 05:32:32 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Mi agenda para la javaOne 2010</title>
		<link>http://sixservix.com/blog/david/2010/09/07/agenda-javaone-2010/</link>
		<comments>http://sixservix.com/blog/david/2010/09/07/agenda-javaone-2010/#comments</comments>
		<pubDate>Tue, 07 Sep 2010 05:11:15 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[david]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[tecnologías de la información]]></category>
		<category><![CDATA[javaone]]></category>
		<category><![CDATA[javaone10]]></category>
		<category><![CDATA[san francisco]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=4304</guid>
		<description><![CDATA[Esta es mi agenda preliminar para la edición 2010 de la javaOne. Comprueba las ponencias a las que asistiré y opina sobre cuales habrían sido tus propias elecciones.


Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/07/23/javaone2010/' rel='bookmark' title='Permanent Link: javaOne 2010'>javaOne 2010</a> <small>David Bonilla se va de vacaciones pagadas a San Francisco...</small></li>
<li><a href='http://sixservix.com/blog/david/2009/12/09/javaone-2010/' rel='bookmark' title='Permanent Link: ¿Habrá JavaOne en 2010?'>¿Habrá JavaOne en 2010?</a> <small>Uno de los principales damnificados de la fusión entre Oracle...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">Después de pelearme durante días con el <a href="http://www.eventreg.com/oracle/openworld2010/sanfrancisco/sb" target="_blank">Schedule Builder</a> -probablemente, una de las aplicaciones web con peor usabilidad y comportamiento de todas las que he utilizado- por fin tengo más o menos perfilada mi agenda para la <strong>javaOne </strong>de este año. Os la presento para que la conozcáis y, si queréis, opinéis sobre la misma.</p>
<p style="text-align: justify">Sé que todos tendréis vuestras propias preferencias y que, seguramente, podréis ayudarme a encontrar esa <em>joyita oculta</em> entre las toneladas de información que proporciona el <em>Builder</em>. Después del documento, os explicaré con qué criterios ha sido construido&#8230; y que significan todos los símbolos y anotaciones manuscritas :)</p>
<p style="text-align: center"><div id="ipaper36979934" class="simpler-ipaper-embed"></div>
<script type="text/javascript">
iPaper_embed('36979934', 'key-hn59ol0t06ltl1xjam0', '600', '450');
</script></p>
<p style="text-align: justify">
<p style="text-align: justify">
<p style="text-align: justify">La agenda está construida con las siguientes pautas:</p>
<ul style="text-align: justify">
<li>He intentado que haya una mezcla entre ponencias puramente técnicas y las más orientadas a <em>negocio</em>.</li>
<li>También hay un equilibrio entre ponencias sobre tecnologías y productos que utiliza mi compañía actualmente (<a href="http://itblog.emc.com/" target="_blank">nubes privadas de EMC</a>) y los que quiero conocer de primera mano como <a href="http://liftweb.net/" target="_blank">Lift</a></li>
<li>He priorizado siempre los paneles y charlas, frente a las presentaciones de &#8220;siéntate, cállate y trágate mi Powerpoint&#8221;</li>
<li>Por <a href="http://javahispano.org/contenidos/es/google_anuncia_que_no_tiene_intencion_de_asistir_a_la_javaone/" target="_blank">motivos evidentes</a>, he eliminado cualquier ponencia impartida por gente de Google</li>
</ul>
<p style="text-align: justify">Revisando la agenda, me doy cuenta de que hay una clara orientación a dos temas principales y&#8230; contradictorios entre sí: <strong>Cloud Computing</strong> y <strong>tunning de la JVM</strong>, que refleja un poco la <em>esquizofrénica</em> realidad que estamos viviendo actualmente.</p>
<p style="text-align: justify">Habréis observado que hay un montón de cruces y rayas. Os explicaré que significa cada cosa:</p>
<ul style="text-align: justify">
<li>Las cruces significan que hay algún evento que, por alguna extraña razón que no he logrado comprender, el <em>Builder</em> no lista. Por ejemplo, todas las <em>Keynotes</em> o presentaciones principales de <a title="Bio de Larry Ellison" href="http://www.maccare.com.ar/biografia_ellison.htm" target="_blank">Primo Larry</a></li>
<li>Las rayitas sobre alguna de las ponencias quieren decir que es improbable que pueda asistir porque coinciden con algún evento o compromiso. El lunes, por ejemplo, es difícil que pueda asistir al taller de <a href="http://www.playframework.org/" target="_blank">Play</a> si quiero pasarme por la <strong>OTN Night</strong> a conocer a alguno de mis compañeros del metal, antes de salir corriendo a la cena organizada por la delegación para España y Portugal de Oracle</li>
<li>En la parte inferior del documento, tenéis recopilados los eventos que no salen listados por el Builder y que completan la agenda. A la izquierda, presentaciones. A la derecha, los eventos vespertinos de <em>networking</em></li>
</ul>
<p style="text-align: justify">En cualquier caso y aunque me prometí el año pasado que no volvería a pegarme semejante paliza, me han vuelto a salir jornadas maratonianas de 8h a 22h. No sé de dónde voy a sacar tiempo para hacer de reportero dicharachero ni, como me ha advertido el gran <a title="Carlos Snachez" href="http://www.slideshare.net/carlossg/presentations" target="_blank">Carlos Sánchez</a>, darme cuenta de que &#8220;<em>lo más interesante de la <strong>javaOne</strong>, ocurre en las fiestas de las noches</em>&#8220;.</p>


<p>Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/07/23/javaone2010/' rel='bookmark' title='Permanent Link: javaOne 2010'>javaOne 2010</a> <small>David Bonilla se va de vacaciones pagadas a San Francisco...</small></li>
<li><a href='http://sixservix.com/blog/david/2009/12/09/javaone-2010/' rel='bookmark' title='Permanent Link: ¿Habrá JavaOne en 2010?'>¿Habrá JavaOne en 2010?</a> <small>Uno de los principales damnificados de la fusión entre Oracle...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/09/07/agenda-javaone-2010/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Arquitectura de logging en Glassfish</title>
		<link>http://sixservix.com/blog/david/2010/08/24/logging-glassfish/</link>
		<comments>http://sixservix.com/blog/david/2010/08/24/logging-glassfish/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 04:50:13 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[glassfish]]></category>
		<category><![CDATA[log4j]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[storetto]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=4107</guid>
		<description><![CDATA[Aprende como funciona el sistema de registro o logging en Glassfish v3 descubriendo el "oscuro secreto" de este servidor de aplicaciones ¿te atreves?


Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/06/02/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-iii/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (III)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (III)</a> <small>Tercera parte del tutorial sobre como utilizar transacciones y bloqueos...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/05/12/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-ii/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (II)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (II)</a> <small>Segunda parte del tutorial sobre como utilizar transacciones y bloqueos...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/05/10/transacciones-bloqueos-glassfish-v3-ejb31-jpa2/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (I)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (I)</a> <small>Un sencillo tutorial sobre como utilizar transacciones y bloqueos con...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-full wp-image-4121" style="margin-right: 15px" title="glassfish" src="http://sixservix.com/blog/david/files/2010/08/glassfish.jpg" alt="Glassfish" width="256" height="256" />Sí, sé lo que estáis pensando: &#8220;¿Un artículo sobre <em>logging </em>en <strong>Glassfish</strong>?&#8221; Los que visitan este <em>blog </em>y no son técnicos ni siquiera habrán llegado a esta línea y los que sí lo sois pensaréis <a title="Glassfish Logging ? WTF ?" href="http://twitter.com/molpe/status/20713037513" target="_blank">&#8220;¿Qué tiene de interesante?&#8221;</a>.</p>
<p style="text-align: justify">Y, sin embargo, lo es. El modo en el que <strong>Glassfish </strong>trabaja con <em>logs </em>es peculiar y guarda algún <em>oscuro secreto</em>.  Sólo te pido <strong>dos cosas:</strong></p>
<ol style="text-align: justify">
<li>
<ol>
<li><strong>Cinco minutos de tu tiempo</strong> para que juzgues si lo he conseguido.</li>
<li>Que, para vivir una experiencia completa, <strong>escuches la canción &#8216;<em>Old Souls</em>&#8216;</strong> de <a href="http://open.spotify.com/album/2qvA7HmSg1iM6XMiFF76dp" target="_blank">la banda sonora de <em>Origen</em></a> mientras lees el artículo.</li>
</ol>
</li>
</ol>
<p style="text-align: justify">Lo peor que te puede pasar es que salgas de aquí aprendiendo algo nuevo y, por supuesto, siempre puedes tirarme <em>tomates virtuales</em> en los comentarios del artículo.  ¿Te animas?</p>
<h3 style="text-align: justify">EL MISTERIO DE LAS TRAZAS INEXPLICABLES</h3>
<p style="text-align: justify">Como parte de mi <em>asedio y conquista</em> al entorno de trabajo de <a href="../../../es/storetto.php" target="_blank">STORETTO</a>, comencé a estudiar nuestro sistema de traza y la configuración del mismo. Parecía algo relativamente sencillo (una configuración típica de <a href="http://es.wikipedia.org/wiki/Log4j" target="_blank">log4j</a>) Sin embargo, algo no encajaba. Ni las trazas aparecían por donde debían ni tenían el formato  que queríamos. Nada se parecía ni remotamente a lo  que teníamos configurado.</p>
<p style="text-align: justify">Tampoco entendía por qué el equipo de <strong>STORETTO </strong>había configurado el sistema de <strong>log4j </strong>habitual de la compañía mediante una variable de sistema, en vez de colocar el fichero de configuración en el <em>classpath </em>de la aplicación.</p>
<p style="text-align: justify"><strong>¿Qué estaba pasando? ¿Era todo esto real o era un sueño? ¿Estaba soñando dentro de un sueño? ¿Cómo distinguir la realidad del sueño?</strong></p>
<p style="text-align: justify">Como en <a href="http://sixservix.com/blog/david/2010/08/18/nbsp-en-xhtml/" target="_blank">el anterior caso de las JSPX desestructuradas</a>, yo tenía un poco más de tiempo disponible que el equipo para comprender <strong>qué estábamos haciendo y por qué lo estábamos haciendo</strong>. Lo que averigüé fue SORPRENDENTE.</p>
<h3 style="text-align: justify"><em>FRAMEWORK </em>DE <em>LOGGING </em>DE GLASSFISH</h3>
<p style="text-align: justify">Antes de nada, era importante conocer qué sistema de registro de trazas utiliza <strong>Glassfish </strong>y cómo funciona el mismo.</p>
<p style="text-align: justify">He resumido todo lo que se necesita saber en un par de párrafos:</p>
<p style="text-align: justify"><strong>Glassfish</strong> utiliza para su sistema de trazas la implementación  por defecto de la especificación <a href="http://jcp.org/aboutJava/communityprocess/review/jsr047/">JSR-047</a>, una API de <em>logging</em>, y recomienda el  uso de la misma, aunque permite el uso de otras como <strong>Apache Commons  Logging</strong> o <strong>log4j</strong>.</p>
<p style="text-align: justify">El uso de la API de <em>logging </em>del JDK implica varias cosas a tener en  cuenta:</p>
<ol style="text-align: justify">
<li>Se basa en un sistema de <strong>Handlers</strong>, clases que heredan de <a href="http://download.oracle.com/javase/1.4.2/docs/api/java/util/logging/Handler.html" target="_blank"><strong>java.util.logging.Handler</strong></a> y que son los que encapsulan tanto la lógica de publicación de trazas  como la configuración de las mismas.</li>
<li>Estableciendo un <em>level</em> o nivel por <strong>Handler</strong> podemos  establecer el nivel mínimo de traza que queremos que recoja el HANDLER.  Estableciendo un nivel determinado se recogerán todas las trazas de ese  nivel y de los niveles superiores jerárquicamente (para conocer más  sobre los nieles de traza, <a title="Niveles de Traza en JDK Logging" href="http://www.lab.dit.upm.es/~lprg/material/apuntes/log/log.htm" target="_blank">pinchar aquí</a>). También se  puede establecer el nivel mínimo de traza <strong>por paquete de clases</strong>,  independientemente del nivel implementado por paquete (se usará la  configuración más restrictiva)</li>
<li>Además del nivel, se puede establecer un control secundario y  opcional sobre lo que se registra o no, mediante la asignación de un  filtro o <strong>Filter</strong> (clase que hereda de <a href="http://download.oracle.com/javase/1.4.2/docs/api/java/util/logging/Filter.html" target="_blank"><strong>java.util.logging.Filter</strong></a>)  a un Handler. Un Filter, básicamente, <a href="http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=/com.ibm.websphere.express.iseries.doc/info/iseriesexp/ae/rtrb_createfilter.html" target="_blank">implementa un método <em>isLoggeable</em></a> que devuelve un booleano que indica si un <em>log </em>se debe trazar o no.</li>
<li>Si se quiere formatear las trazas generadas con alguna estructura  especifica, se debe implementar un <strong>Formatter</strong> (clase que herede <a href="http://download.oracle.com/javase/1.4.2/docs/api/java/util/logging/Formatter.html" target="_blank"><strong>java.util.logging.Formatter</strong></a>)  y asignarlo al Handler deseado.</li>
<li>Toda esta configuración se hace a través de un fichero denominado <em>logging.properties</em></li>
</ol>
<p style="text-align: justify">La primera diferencia que chocará a todos los que venimos de usar <strong>log4j </strong>es que todo se configura programándolo. Es decir, no tienes una manera de poder configurar de forma flexible el formato de tus trazas. Si quieres un <strong>Formatter</strong> que saque el patrón de tu traza de un fichero de propiedades, vas a tener que programártelo.</p>
<h3 style="text-align: justify">TRABAJANDO CON LOG4J</h3>
<p style="text-align: justify">
<div id="attachment_4192" class="wp-caption alignright" style="width: 298px"><a href="http://sixservix.com/blog/david/files/2010/08/origen-glassfish.jpg"><img class="size-full wp-image-4192  " title="origen-glassfish" src="http://sixservix.com/blog/david/files/2010/08/origen-glassfish.jpg" alt="" width="288" height="411" /></a><p class="wp-caption-text">¿Son mis logs reales o sólo un sueño?</p></div>
<p style="text-align: justify">
<p style="text-align: justify">Para trabajar con <strong>log4j </strong>en <strong>Glassfish v2 </strong><a href="http://www.david-sanmartin.net/2009/11/configuracion-de-log4j-glassfish-para-desarrollo/" target="_blank">se recomendaba</a> configurar la librería  de traza como librería del sistema para evitar problemas con el <em>classloading</em> pero esto ya no puede hacerse con <strong>Glassfish v3</strong> así que <a href="http://nzpcmad.blogspot.com/2009/10/log4j-path-to-properties-file.html" target="_blank">la solución</a> pasa por indicar al servidor la ruta del fichero de configuración de <strong>log4j</strong>.</p>
<p style="text-align: justify">En <strong>log4j </strong>se configuran <em>Appender </em>(el equivalente de los Handler en  JSR-047) El <em>Appender </em>típico que todo el mundo utiliza al desarrollar es el <a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/ConsoleAppender.html" target="_blank"><em>org.apache.log4j.ConsoleAppender</em></a>, que publica los <em>logs</em> en la salida por defecto de <em>System.out</em>.</p>
<p style="text-align: justify">El problema es que las trazas no salen por la <em>consola </em>habitual que esperamos todos los programadores sino en un fichero <em>server.log</em> que se encuentra en la ruta <em>/midominio/logs/</em>.</p>
<p style="text-align: justify">Eso es bastante fácil de explicar porque  <strong>ese fichero es <a href="http://forums.java.net/jive/thread.jspa?threadID=52977" target="_blank">la salida por defecto del servidor</a></strong>, así que, ésa es su <em>consola</em>.</p>
<p style="text-align: justify">Lo que <strong>no tiene ni pies ni cabeza</strong> es que <strong>nuestras trazas salgan con el formato de las trazas de la API de <em>logging </em>de JDK</strong> o, más exactamente, <em>envueltas </em>por su formato, puesto que nuestro traza aparece&#8230; pero sólo como parte del mensaje de la traza de <em>logging </em>del JDK.</p>
<p style="text-align: justify">Bueno&#8230; podemos pensar que, de alguna manera, el sistema está ignorando nuestra configuración de <strong>log4j</strong>. Sin embargo, si configuramos cualquier otro <em>Appender</em>, por ejemplo uno que publique en un fichero <em>inception.log</em>, <strong>log4j </strong>funciona PERFECTAMENTE.</p>
<p style="text-align: justify">¿Entonces? <strong>¿Qué está pasando?</strong> ¿Por qué salen todas mis trazas rodeadas de almohadillas &#8216;#&#8217;  y con un retorno de carro cuando las publico por consola?</p>
<h3 style="text-align: justify">LA SOLUCIÓN AL MISTERIO</h3>
<p style="text-align: justify">No, no estamos soñando. Nuestras trazas son reales y nuestra configuración también. No estamos haciendo nada <em>mal</em>. Simplemente, alguien ha estado jugando con nosotros. Alguien ha estado <em>haciendo trampas</em>.</p>
<p style="text-align: justify"><strong>Glassfish</strong>, utiliza una implementación propia y sobrescrita del objeto <a href="http://download.oracle.com/javase/1.4.2/docs/api/java/lang/System.html" target="_blank">System</a> cuyo método <em>out </em>devuelve un <em>PrintWriter </em>que redirige todas las salidas al sistema de <em>logging</em> del servidor. Probadlo, hacer un <em>System.out.println</em> en una clase desplegada en <strong>Glassfish</strong>. No sólo aparecerá en la salida por defecto -server.log- sino que, además, aparecerá con el formato específico del sistema de <em>logging</em>.</p>
<p style="text-align: justify">Lo más <em>grave </em>de todo esto es que <em>System </em>es una clase final. Es decir, que no puede ser extendida, precisamente para evitar lo que <strong>Glassfish </strong>ha conseguido: que nuestro código tenga un comportamiento extraño y nos desconcierte. <strong>Que nos tengamos que frotar los ojos para comprobar que no estamos soñando</strong>.</p>
<p style="text-align: justify">De acuerdo, <strong>Glassfish </strong>nos ha engañado pero ahora, después de leer este artículo sabemos cómo vencerlo:</p>
<ul style="text-align: justify">
<li><strong>¿Queremos modificar el formato de las trazas del servidor? </strong>Implementaremos nuestro propio <em>Formatter </em>y se lo asignaremos al <em>ConsoleHandler </em>del fichero <em>logging.properties</em></li>
<li><strong>¿Queremos que nuestras propias trazas no se mezclen con las del servidor?</strong> Nos olvidaremos de utilizar el <em>ConsoleAppender</em></li>
<li><strong>¿Queremos que sólo nuestras trazas de error salgan en la salida por defecto del servidor?</strong> Podremos utilizar un <em>ConsoleAppender </em>y configurarlo en nuestro <em>log4j.properties</em> para que sólo registre trazas de nivel ERROR o superiores (recordad que sea cual sea el nivel de traza de<strong> log4j</strong>, la salida se publicará en <em>System.out</em> y el <em>logging </em>de JAVA las publicará por defecto como trazas de nivel INFO)</li>
</ul>
<p style="text-align: justify"><strong>Glassfish </strong>ha luchado contra nosotros y ha perdido, por lo menos a nivel de <em>logging</em>. Nosotros le dominamos. No él, a nosotros. Y, desde luego, <strong>no estamos soñando</strong>&#8230; ¿o sí?</p>
<p style="text-align: justify"><span style="color: #339966"><strong>BONILINKS:</strong></span></p>
<ul>
<li><a href="https://issues.sonatype.org/browse/NEXUS-1307" target="_blank">Gente despotricando sobre el tweaking de System de Glassfish</a></li>
<li><a href="http://forums.terracotta.org/forums/posts/list/1957.page" target="_blank">Gente flipando con el comportamiento de System.out</a></li>
<li><a href="http://www.javadocexamples.com/java_source/com/sun/enterprise/server/logging/UniformLogFormatter.java.html" target="_blank">La fuente del UniformLogFormatter</a> (o el origen del formato de traza infernal de <strong>Glassfish</strong>)</li>
<li><a href="http://wiki.glassfish.java.net/Wiki.jsp?page=FaqConfigureLogging" target="_blank">Información Oficial de Glassfish sobre configuración de <em>logging</em></a>, donde se les olvida comentar lo del <em>asuntillo </em>del <em>System.out</em>&#8230;</li>
<li><a href="http://www.crazysquirrel.com/computing/java/logging.jspx" target="_blank">Información para entender lo básico de la API Java Logging</a></li>
</ul>
<p style="text-align: justify">
<p style="text-align: justify">


<p>Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/06/02/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-iii/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (III)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (III)</a> <small>Tercera parte del tutorial sobre como utilizar transacciones y bloqueos...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/05/12/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-ii/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (II)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (II)</a> <small>Segunda parte del tutorial sobre como utilizar transacciones y bloqueos...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/05/10/transacciones-bloqueos-glassfish-v3-ejb31-jpa2/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (I)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (I)</a> <small>Un sencillo tutorial sobre como utilizar transacciones y bloqueos con...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/08/24/logging-glassfish/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>javaOne 2010</title>
		<link>http://sixservix.com/blog/david/2010/07/23/javaone2010/</link>
		<comments>http://sixservix.com/blog/david/2010/07/23/javaone2010/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 04:50:46 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[david]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[tecnologías de la información]]></category>
		<category><![CDATA[javaone]]></category>
		<category><![CDATA[javaone10]]></category>
		<category><![CDATA[javaOne2010]]></category>
		<category><![CDATA[oracle]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=3672</guid>
		<description><![CDATA[David Bonilla se va de vacaciones pagadas a San Francisco para asistir a la mayor conferencia de desarrolladores de la historia ¿Conseguirá regresar?


Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/09/07/agenda-javaone-2010/' rel='bookmark' title='Permanent Link: Mi agenda para la javaOne 2010'>Mi agenda para la javaOne 2010</a> <small>Esta es mi agenda preliminar para la edición 2010 de...</small></li>
<li><a href='http://sixservix.com/blog/david/2009/12/09/javaone-2010/' rel='bookmark' title='Permanent Link: ¿Habrá JavaOne en 2010?'>¿Habrá JavaOne en 2010?</a> <small>Uno de los principales damnificados de la fusión entre Oracle...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-full wp-image-3679" title="GOLDEN_GATE" src="http://sixservix.com/blog/david/files/2010/07/GOLDEN_GATE.jpg" alt="" width="241" height="278" />A partir del próximo 19 de septiembre se celebrará en San Francisco la <strong>javaOne</strong>, el mayor evento mundial sobre la plataforma Java y sus tecnologías asociadas y, un año más,  me infiltraré en <em>modo comando</em> entre los mejores técnicos del planeta para disfrutar, aprender y contároslo. Eso sí, a mi manera, <em>alla Bonilla</em>.</p>
<p style="text-align: justify">Sé que <strong>soy un privilegiado</strong> por disfrutar del apoyo de <strong>Sixservix</strong> para volver a  asistir a la conferencia. Un apoyo que, desgraciadamente, es difícil  de encontrar en el sector de las TI en España y América latina. Pero, en cualquier caso, conozco gente que, aún pudiendo asistir, <span style="text-decoration: underline">ni siquiera se lo ha planteado</span>; bien por desconocimiento del evento en sí, bien por antiguas y falsas creencias o leyendas. Así que, permitidme que os explique qué espero encontrar allí, qué pienso hacer y  cómo pretendo hacerlo. Ojalá que, cuando acabéis de leer este artículo, todos estéis deseando acompañarme. Si no este año, quizás el siguiente.</p>
<h3 style="text-align: justify">UNA CIUDAD. UNA SEMANA. TRES CONFERENCIAS</h3>
<p style="text-align: justify">Ya <a href="http://javahispano.org/contenidos.item.action?id=745480&amp;menuId=MINDS" target="_blank">comenté el año pasado</a> como la <strong>javaOne</strong> cumplía con las 3 Bs: <em>bueno, bonito y barato</em>. Este año, después de unos meses de incertidumbre en los que ni siquiera sabiamos si iba a celebrarse, nos encontramos con que Oracle, el nuevo amo y señor de Java, ha montado la mundial. No sólo sigue celebrándola sino que ha decidido juntarla con <strong>Develop</strong>, su conferencia de desarrolladores,  y <strong>OpenWorld</strong>, su evento más orientado a <em>tíos-que-manejan-la-pasta</em> y <em>cuellocorbatas</em>.</p>
<p style="text-align: justify">La primera consecuencia de todo esto es que <strong>San Francisco va a estallar</strong>. Si a los 15.ooo asistentes de la javaOne les sumas los 43.ooo <em>trolorolos</em> que asistieron a la OpenWorld del año pasado y <a href="http://www.crn.com/software/220601223" target="_blank">reservaron 81.000 habitaciones de hotel</a>, te encuentras con que es más facil conseguir batir el <a href="http://www.youtube.com/watch?v=HQZUg2wH_vQ" target="_blank">récord olímpico de petanca</a> que conseguir una habitación de hotel económica en la ciudad del Golden Gate.</p>
<p style="text-align: justify">La segunda consecuencia es que, durante una semana, <strong>San Francisco probablemente disfrute del mayor número de técnicos y desarrolladores reunidos de la historia</strong>. Porque, a la tremenda <em>horda invasora</em>, hay que sumar la población local de tipejos que desarrollan cosas como Twitter, Google o cacharros como los de Apple o Hewlett-Packard.</p>
<p style="text-align: justify">En definitiva, <strong>2.150 sesiones</strong> condensadas en una sóla ciudad y una sóla semana. La posibilidad de asistir a charlas de cualquier tecnología o lenguaje que se te pueda ocurrir impartidas por los mejores: sus creadores. Y, por supuesto, la posibilidad de conocerlos.</p>
<p style="text-align: justify">No hay nada ni remotamente parecido en el mundo de las tecnologías de la información. Ni en tamaño ni en posibilidades. Ni para aprender, ni para hacer <em>networking</em>. <strong>Nada se acerca a lo que va a verse en esta JavaOne</strong>.</p>
<h3 style="text-align: justify">LA MISIÓN: LIARLA PARDA</h3>
<p style="text-align: justify">¿Y qué espero este año de la javaOne? ¿Qué pretendo hacer allí? Evidentemente, dar un paso más en mi p<em>lan secreto para dominar el mundo</em> y, de paso, aprender todo lo que pueda, conocer gente interesante y divertirme. Voy a intentar resumir en 6 puntos mis expectativas:</p>
<p style="text-align: justify"><img class="alignright" title="latinPower" src="http://sixservix.com/blog/david/files/2010/07/latinPower.jpg" alt="" width="266" height="256" /></p>
<ul style="text-align: justify">
<li><strong>APRENDER MUCHO</strong>. Sí, es verdad que con Internet no hace falta asistir físicamente a una conferencia para aprender cualquier conocimiento pero, sinceramente, ¿cuántos de nosotros tenemos tiempo en nuestro día a día para ponernos a leer complejos tutoriales o sumergirnos en vídeos y vídeos de charlas y ponencias? La javaOne permite que durante una semana, nos aislemos de todo y de todos y nos dediquemos a lo que más nos gusta: aprender.</li>
<li><strong>HACER NETWORKING</strong>. Sí, <em>networking,</em> pero del de verdad. Espero conocer a mucha <em>gente-que-de-verdad-hace-cosas</em> como los denomina Alberto Molpeceres. Todo lo contrario a los eventos de tipo &#8220;reinventa Internet&#8221; que han crecido como setas en mi país.</li>
<li><strong>CREAR COMUNIDAD</strong>. El año pasado constaté que los hispanohablantes éramos más de los que cualquiera pudiera creer pero, al contrario que <a href="http://www.gujavasc.org.br/wp-content/uploads/2008/05/dsc00038.JPG" target="_blank">los brasileños</a>, nos falta marketing. Espero que en esta javaOne se oiga el castellano más que nunca. Por mí no va a quedar.</li>
<li><strong>COMUNICAR, COMUNICAR, COMUNICAR</strong>. Si el año pasado perdí horas de sueño haciendo las crónicas del día para <a href="http://www.javahispano.org/" target="_blank">javaHispano</a>, este año el trabajo se multiplica. No sólo intentaré enviar las crónicas diarias, sino que podréis leer la versión <em>gamberra</em> y desenfadada de las mismas en <strong>este blog</strong>. Además, nuestras cuentas de twitter echarán humo, por supuesto y, como gran novedad&#8230; MEGATÓN: intentaré retrasmitir al más puro estilo reportero dicharachero mediante screencast. Eso, si consigo averiguar cómo funciona la cámara que me regaló Jeroclo por mi cumpleaños.</li>
<li><strong>COMER PATO LAQUEADO EN CHINATOWN</strong>. Una sana costumbre que instauramos <a href="http://www.pgcon.org/2010/schedule/speakers/166.en.html" target="_blank">Álvaro Hernandez</a> y yo el año pasado y a la que esperemos que se sumen los nuevos fichajes de este año: <a href="http://weblogs.javahispano.org/jh/entry/nos_presentamos_ii" target="_blank">Erick Camacho</a>, compañero del metal en javaHispano, y <a href="http://twitter.com/jerolba" target="_blank">Jeroclo, el espartano</a>, amigo, camarada y socio, en representación de <a href="http://www.funius.com" target="_blank">Funius</a>. Por supuesto, habrá que ir a disfrutar del <em>brunch</em> del domingo al <a href="http://www.intercontinentalmarkhopkins.com/top_of_the_mark/" target="_blank">Top of the Mark</a> y seguro que caerá más de una porción de tarta en el <a href="http://www.thecheesecakefactory.com/menu/Cheesecake/white_chocolate_raspberry_truffle" target="_blank">Cheesecake Factory</a> de Union Square. Al fin y al cabo, las tradiciones están para respetarlas, ¿no? :P</li>
</ul>
<h3 style="text-align: justify">BONILLA 3.0</h3>
<p style="text-align: justify">Este año todo ha cambiado, TODO es diferente. Y no sólo hablo de la compra de SUN por parte de Oracle, sino de cambios a nivel personal y profesional que, en parte, han sido motivados o acelerados por mi visita a la última edición. <strong>Apenas me reconozco</strong> cuando pienso en el Bonilla que asistió a la edición del año pasado.</p>
<p style="text-align: justify"><a href="http://sixservix.com/blog/david/2009/07/22/nulla-dies-sine-linea/" target="_blank">Hace un año,</a> este blog no existia. Hace un año, no conocía a toda la gente interesante que me ha enriquecido en los últimos 365 días. Hace un año, ni siquiera estaba viviendo con mi novia, que en menos de 3 meses se convertirá en mi mujer. Hace  un año, no tenía cuenta en <strong>Twitter</strong>. Hace un año, España ni siquiera soñaba con ser campeona del mundo. Hace un año, <a href="http://sixservix.com/blog/david/2010/04/27/scrum-master/" target="_blank">no era ágil</a>. Pero, sobre todo, hace un año, no tenía tan claro como ahora qué es lo que quiero hacer y cómo lo quiero hacer.</p>
<p style="text-align: justify"><img class="aligncenter" title="David Bonilla" src="http://sixservix.com/blog/david/files/2010/01/david_bonilla.jpg" alt="" width="600" height="187" /></p>
<p style="text-align: justify">La asistencia a la <strong>javaOne</strong> del año pasado consiguió que me enamorara definitivamente de mi profesión. Que me diera cuenta de que las cosas que no me gustaban de ella no tenían que ver con LO QUE hacía sino con CÓMO lo hacía. Hace un año, vi que había otro modo de hacer las cosas y que te podías ganar muy bien la vida haciéndolas.</p>
<p style="text-align: justify">Al acudir a la javaOne, pude conocer a gente que estaba a <em>años luz</em> de mi círculo de influencia, como <a href="http://kohsuke.org/about/" target="_blank">Kohsuke Kawaguchi</a> o <a href="http://netbeans.org/community/articles/interviews/dreamprofile-senger.html" target="_blank">Vinicius Senger</a>, tuve la posibilidad de acercarme a tecnologías y proyectos antes de que se difundieran en España y demostrarme a mí mismo que puedo defenderme con mi inglés en Estados Unidos, Albacete o Sebastopol.</p>
<p style="text-align: justify">Hace algunos años, perdí <strong>25 kg</strong> y cambié de estilo de vida. Mis amigos se sorprendieron tanto que bromeaban llamándome &#8220;<em>David 2.0</em>&#8220;. Durante este año, creo que he cambiado tanto que he pasado a la siguiente <em>release</em> y puedo considerarme &#8220;<em>Bonilla 3.0</em>&#8220;.</p>
<p style="text-align: justify">No, no me he vuelto loco. No creo que la javaOne me haya cambiado la vida pero, sí estoy seguro de que sirvió como <em>trigger</em> para ayudarme a reconocer qué es lo que quería hacer con mi trabajo y mi profesión y comenzara a dar los pasos necesarios para lograrlo.</p>
<h3 style="text-align: justify">CONCLUSIONES</h3>
<p style="text-align: justify">Un año más, debo agradecer la confianza y soporte de <strong>Sixservix</strong> que me va a permitir asistir a la conferencía. Además, Jeroclo, Erick y un servidor viajamos a la conferencia con entradas gratuitas de <em>bloggers</em> por deferencia de <strong>Oracle</strong> en general y su Directora de Comunicación para España y Portugal en particular, <a href="http://twitter.com/mildredlaya" target="_blank">Mildred Laya</a>, que nos ha hecho sentirnos &#8220;importantes&#8221; aunque sepamos que no lo somos.</p>
<p style="text-align: justify">Al que sea mal pensado y crea que nos hemos vendido a <strong>Oracle</strong>, decirle que no sabe de lo que habla. Yo no podría venderme jamás a Oracle. Todo el mundo sabe que Microsoft paga mucho más.</p>
<p style="text-align: justify">Al que haya llegado hasta aquí y vaya a ir a la <strong>javaOne</strong>, animarle a que se ponga en contacto conmigo a través del <a href="http://sixservix.com/blog/david/about/" target="_blank">formulario de contacto</a> de este <em>blog</em>. Cuantos más seamos, mejor, más ruido haremos y mejor nos lo pasaremos.</p>
<p style="text-align: justify">Si, por el contrario, aún no tienes entrada, te recuerdo que <strong>el periodo de <em>early bird</em> o precio reducido ha sido prorrogado hasta el 30 de julio</strong>. Aún estás a tiempo de animarte y venirte a San Francisco. Te costará bastate menos que cualquier curso de formación de alto nivel de una semana que puedas tomar en España.</p>
<p style="text-align: justify">En cualquier caso, y como a veces pido a los amigos, <strong>difundid <em>la palabra de Bo</em></strong>: retwittead, reenviad o mandad por correo este artículo. Que no haya ni un sólo hispanohablante que vaya a la javaOne y no se una a nuestra <em>Spanish Armada</em>. Este año, vamos a por todas y aquí te lo contaremos.</p>


<p>Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/09/07/agenda-javaone-2010/' rel='bookmark' title='Permanent Link: Mi agenda para la javaOne 2010'>Mi agenda para la javaOne 2010</a> <small>Esta es mi agenda preliminar para la edición 2010 de...</small></li>
<li><a href='http://sixservix.com/blog/david/2009/12/09/javaone-2010/' rel='bookmark' title='Permanent Link: ¿Habrá JavaOne en 2010?'>¿Habrá JavaOne en 2010?</a> <small>Uno de los principales damnificados de la fusión entre Oracle...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/07/23/javaone2010/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Papá ¿Por qué siempre usamos .NET?</title>
		<link>http://sixservix.com/blog/david/2010/07/02/papa/</link>
		<comments>http://sixservix.com/blog/david/2010/07/02/papa/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 04:50:06 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[humor]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[javazone]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=3438</guid>
		<description><![CDATA[¿Java o .NET? ¿Sega o Nintendo? ¿Cocacola o Pepsi? Durante toda nuestra vida nos han empujado a posicionarnos, a elegir innecesariamente entre una y otra cosa.]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">¿<strong>Java</strong> o <strong>.NET</strong>? ¿Sega o Nintendo? ¿Cocacola o Pepsi? ¿Sabrina Salerno o Samantha Fox? Durante toda nuestra vida nos han empujado a posicionarnos, a elegir innecesariamente entre una y otra cosa en vez de disfrutar de lo mejor que te proporcione cada una de ellas.</p>
<p style="text-align: justify">Todo esta introducción, sólo es una excusa para presentaros <strong>el mejor vídeo sobre java que se ha hecho nunca</strong>. Cuando digo nunca es NUNCA. Simplemente, IMPRESCINDIBLE. Disfrutadlo&#8230;</p>
<p style="text-align: center"><p><a href="http://sixservix.com/blog/david/2010/07/02/papa/"><em>Pinche aquí para ver el vídeo</em></a></p></p>
<p style="text-align: justify">Es el impresionante <em>trailer</em> que ha creado la gente de <a href="http://jz10.java.no/index.html" target="_blank">JavaZone</a>, una conferencia de desarrolladores celebrada en Escandinavia con más de <strong>2300 entradas vendidas</strong>.</p>
<p style="text-align: justify">Dedicado a la gente de <a href="http://twitter.com/AltNetHispano" target="_blank">AltNetHispano</a> -que tan bien lo están haciendo- en general y a <a href="http://twitter.com/amaliahern" target="_blank">Amalia Hernandez</a> en particular.</p>
<p style="text-align: justify">(Visto en <a href="http://www.meneame.net/story/papa-siempre-usamos-net-eng" target="_blank">Meneame</a>, donde los comentarios demuestran que, desgraciadamente, aún hay gente que cree que hay lenguajes buenos y malos, no buenos o malos programadores&#8230;)</p>
<p style="text-align: justify"><span style="color: #008000"><strong>PEDAZO DE DISCLAIMER:</strong></span></p>
<p style="text-align: justify"><strong><span style="color: #008000">Este vídeo me llegó el fin de semana pasada e inmediatamente redacté este <em>post </em>como boniartículo humorístico para el siguiente viernes. Cuando vi que <a href="http://twitter.com/dani_latorre/status/17020586276" target="_blank">ya lo habían publicado</a> en su cuenta de <em>twitter </em>gente como Dani Latorre, Erick Camacho o Sergi Almar también lo hice <a href="http://twitter.com/david_bonilla/status/17077706736" target="_blank">en la mía</a> pero, mantuve la publicación del artículo para el siguiente viernes.</span></strong></p>
<p style="text-align: justify"><strong><span style="color: #008000">Después vi que el vídeo había corrido como la espuma por Internet y que hasta Abraham había hecho <a href="http://javahispano.org/contenidos/es/divertido_trailer_publicitario_de_javazone/" target="_blank">referencia al mismo en javaHispano</a>. Aún así, lo mantuve. Primero <span style="text-decoration: underline">porque soy un cabezón</span> :) y, segundo, porque quiero creer -ayudado por las estadísticas de Google Analytics- que no todo el mundo que me lee viene de jH  (&#8220;sólo&#8221; un 14,16%&#8230;).</span></strong></p>
<p style="text-align: justify"><strong><span style="color: #008000">Hoy, al repasar el artículo por última vez, me he alegrado profundamente de haber esperado hasta el viernes para publicarlo porque, lo que se dice modula completamente el &#8220;polémico&#8221; <a href="http://sixservix.com/blog/david/2010/06/30/porque-java-apesta-y-c-sharp-mola/#idc-container" target="_blank">artículo del miércoles</a> y me ha animado a escribir este <em>disclaimer</em>.<br />
</span></strong></p>
<p style="text-align: justify"><strong><span style="color: #008000">Aún así, puede haber algún <em>bocachancla </em>que diga que este artículo es oportunista y se ha escrito posteriormente. Lo estoy esperando. Menos mal que el bendito sistema de gestión de Wordpress guarda un histórico de cambios con hora y fecha&#8230;</span></strong></p>
<p style="text-align: justify"><strong><span style="color: #008000">Un saludo a todos y que viva .NET, Java, Ruby y Fortran. Como he dicho muchas veces, tenemos la profesión más bonita del mundo. Da igual el lenguaje que utilicemos&#8230;</span></strong></p>
<p style="text-align: justify"><span style="color: #008000"><strong>PS: Una última mención de agradecimiento a <a href="http://jorgerubira.blogspot.com/" target="_blank">Jorge Rubira</a> que encontró una versión alternativa del vídeo después de que lo hubieran retirado de YouTube.</strong></span></p>
]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/07/02/papa/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Porque Java apesta y C# mola</title>
		<link>http://sixservix.com/blog/david/2010/06/30/porque-java-apesta-y-c-sharp-mola/</link>
		<comments>http://sixservix.com/blog/david/2010/06/30/porque-java-apesta-y-c-sharp-mola/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 04:42:16 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[Jeffrey Zhao]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=3453</guid>
		<description><![CDATA[Según Jeffrey Zhao, Java es un truño infumable y C# el futuro inmediato. ¿Tiene esta afirmación alguna base técnica real? Descúbrelo en este artículo.


Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2009/08/21/gestion-de-memoria-en-java/' rel='bookmark' title='Permanent Link: Gestión de memoria en Java'>Gestión de memoria en Java</a> <small>Hace poco me llegó un correo de un compañero del...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">He programado en Java durante toda mi carrera profesional. He utilizado otros lenguajes como <strong>C </strong>o <strong>ensamblador</strong>, y uso <strong>HTML</strong>, <strong>JavaScript</strong> o <strong>SQL</strong> en mi día a día como todo hijo de vecino pero, al final, mi confort zone siempre ha sido el territorio de James Gosling y Duke.</p>
<p style="text-align: justify">He de reconocer que, hasta hace poco, era un relativo <em>fanboy</em> de java pero, cada día soy más agnóstico respecto al lenguaje y me interesa más el producto; lo que, traducido a cristiano, significa que me da igual como esté hecho algo, lo importante es las funcionalidades que implemente y, por supuesto, que esté bien hecho.</p>
<p style="text-align: justify">Y en este estado de las cosas, ha caído en mis manos una maravillosa presentación de <strong>Jeffrey Zhao </strong>titulada “Porque Java apesta y C# mola”. El texto es imprescindible, lo mires por donde lo mires. No sólo porque supone una comparativa técnica y científica que rebosa calidad por todos los lados, sino porque detrás de un título de apariencia <em>troll</em>, se esconde una reflexión realista y desapasionada en la que no se aprecia fanatismo alguno.</p>
<p style="text-align: justify">Pero lo más importante de todo es que <span style="text-decoration: underline"><strong>Jeffrey Zhao</strong> SE MOJA</span>. Es de agradecer que alguien tome posición, la argumente y sea lo suficientemente valiente como para hacerla pública y, a lo torero, pedir réplica a la misma con la frase “contacta conmigo, muéstrame tu idea&#8230; y pruébala” proporcionando su <a href="http://blog.zhaojie.me/" target="_blank">blog</a>, correo y <a href="http://www.twitter.com/jeffz_cn" target="_blank">cuenta de twitter</a>. Ahí es nada.</p>
<p style="text-align: justify">Por si fuera poco, las diapositivas están salpicadas de frases memorables y un fino humor que es difícil de encontrar en un texto técnico. Me ha encantado la reflexión  “si la <strong>JVM </strong>es la máquina, los <em>byte codes</em> son el código máquina y programar en Java&#8230; es como programar en ensamblador ¿De verdad quieres programar en ensamblador?”. Sencillamente, brillante.</p>
<p style="text-align: justify">El texto finaliza con una reflexión: ni siquiera nos pide que cambiemos de plataforma, entendiendo como plataforma la <strong>JVM</strong>, sino que pregunta ¿Por qué no utilizar otros lenguajes más poderosos a nivel de sintaxis y que se pueden utilizar dentro de la <strong>JVM </strong>como <strong>Scala</strong>, <strong>Ruby </strong>(JRuby) o <strong>Python </strong>(Jhyton)?</p>
<p style="text-align: justify">Qué grande es Jeffrey Zhao y qué grande es esta presentación. Tengo el orgullo de presentárosla aquí:</p>
<p style="text-align: center"><object width="400" height="328"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=why-java-sucks-and-csharp-rocks-100418041313-phpapp02"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=why-java-sucks-and-csharp-rocks-100418041313-phpapp02"  type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="400" height="328"></embed></object></p>
<p style="text-align: justify">La conclusión a la que llego después de haber leído la presentación es que Jeffrey, como tantos otros, no nos está pidiendo a los que venimos del mundo Java que abandonemos la <strong>JVM </strong>ni la potencia de todo el mundo de librerías que hay detrás de ella, sino que probemos otros lenguajes que se pueden ejecutar en la misma.</p>
<p style="text-align: justify">¿Realmente merece la pena hacerlo cuando desgraciadamente hay un alto porcentaje de programadores a los que les suena a chino la mayoría de las cosas de las que habla Jeffrey? Bueno&#8230; depende. Si formas parte de una maligna megacorporación, puede que no, pero, si eres miembro de un pequeño y altamente productivo equipo de desarrollo&#8230;, a lo mejor el hecho de utilizar un lenguaje donde poder ordenar un <em>array </em>pasando la lógica de ordenación como parámetro, en vez de implementando una clase <em>Comparator, </em>marca la diferencia.</p>
<p style="text-align: justify">Voy a echarle un vistazo a <strong>Scala</strong>&#8230;</p>


<p>Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2009/08/21/gestion-de-memoria-en-java/' rel='bookmark' title='Permanent Link: Gestión de memoria en Java'>Gestión de memoria en Java</a> <small>Hace poco me llegó un correo de un compañero del...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/06/30/porque-java-apesta-y-c-sharp-mola/feed/</wfw:commentRss>
		<slash:comments>40</slash:comments>
		</item>
		<item>
		<title>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (III)</title>
		<link>http://sixservix.com/blog/david/2010/06/02/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-iii/</link>
		<comments>http://sixservix.com/blog/david/2010/06/02/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-iii/#comments</comments>
		<pubDate>Wed, 02 Jun 2010 04:50:00 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[ejb]]></category>
		<category><![CDATA[ejb3.1]]></category>
		<category><![CDATA[gist]]></category>
		<category><![CDATA[gisthub]]></category>
		<category><![CDATA[glassfish]]></category>
		<category><![CDATA[glassfish v3]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[JPA2]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=3150</guid>
		<description><![CDATA[Tercera parte del tutorial sobre como utilizar transacciones y bloqueos con JPA2 en Glassfish v3 con JPA2.


Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/08/24/logging-glassfish/' rel='bookmark' title='Permanent Link: Arquitectura de logging en Glassfish'>Arquitectura de logging en Glassfish</a> <small>Aprende como funciona el sistema de registro o logging en...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/05/12/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-ii/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (II)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (II)</a> <small>Segunda parte del tutorial sobre como utilizar transacciones y bloqueos...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/05/10/transacciones-bloqueos-glassfish-v3-ejb31-jpa2/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (I)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (I)</a> <small>Un sencillo tutorial sobre como utilizar transacciones y bloqueos con...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-medium wp-image-3153" style="margin-right: 10px" src="http://sixservix.com/blog/david/files/2010/05/jpa_ejb3_3-195x300.jpg" alt="jpa_ejb3_3" width="195" height="300" />Tercera entrega y última, por el momento, del <em>megatutorial </em>sobre transacciones y bloqueos con <strong>EJB3.1</strong> y <strong>JPA2</strong> sobre <strong>Glassfish v3</strong>.</p>
<p style="text-align: justify">Mientras que en la <a href="http://sixservix.com/blog/david/2010/05/10/transacciones-bloqueos-glassfish-v3-ejb31-jpa2/" target="_blank">primera entrega</a> dejamos configurado el servidor y en la <a href="http://sixservix.com/blog/david/2010/05/12/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-ii/" target="_blank">segunda</a> configuramos el proyecto en <strong>Netbeans</strong>, en esta estudiaremos directamente el código que nos permitirá trabajar con transacciones y bloqueos.</p>
<p style="text-align: justify">Nuestro proyecto web va a ser más simple que el asa de un cubo. Constará de un <em>servlet</em><strong> </strong>escrito &#8220;a pelo Capello&#8221; denominado RenombraServlet, un EJB<em> Stateless</em> llamado ActualizaCliente , dos EJBs de sesión tan míseros que no merecen ni ser mencionados, aunque nos ayudaran a probar como conseguir transacciones y bloqueos pesimistas, y optimistas con <strong>EJB3.1</strong>; y, por último, dos EJBs de entidad &#8211; Customer y Order- que facilitan el mapeo entre la base de datos y nuestra aplicación.</p>
<p style="text-align: justify"><strong>¿Qué hace nuestra aplicación?</strong> Sencillo. Cuando se invoque el <em>servlet</em> se buscará al cliente con ID = 1. Si no existe, nos crearemos un cliente llamado &#8220;José María Arranz&#8221;, si existe, lo renombraremos dos veces por código aunque podremos comprobar que, en el mejor de los casos, sólo se modificará el nombre del cliente una única vez.</p>
<p style="text-align: justify">Una vez descritos de forma genérica la aplicación y su funcionamiento, os presentaré las clases una a una y, finalmente, os explicaré cómo se consiguen transacciones y bloqueos con las mismas.</p>
<h3 style="text-align: justify">1. EL SERVLET Y EL EJB RENOMBRADOR</h3>
<p style="text-align: justify">
<p style="text-align: justify">La clase <em>RenombraServlet.java</em> es el punto de acceso de la aplicación. Por obra y gracia de la especificación 3.0 de <em>servlets </em>se autoconfigura con una  ruta de acceso <em>/RenombraServlet</em>, así que ya sabéis, para acceder a la aplicación vía el servletcito:  <em>http://tuhost:tupuerto/tucontexto/RenombraServlet</em></p>
<p style="text-align: justify">Una cosa importante a tener en cuenta es que se puede invocar al método con un parámetro opcional <em>lock </em>que te permitirá hacer renombrados con distintos bloqueos y que os explicaré más adelante.</p>
<p style="text-align: justify">Así, por ejemplo, si invocáis al servlet con el parámetro lock con valor 1 (<em>http://tuhost:tupuerto/tucontexto/RenombraServlet?lock=1</em>), estaréis renombrando al cliente &#8220;José María Arranz&#8221; con un bloqueo pesimista con un NOWAIT como una casa de grande.</p>
<p style="text-align: justify">Básicamente, es un <em><a href="http://en.wikipedia.org/wiki/Java_Servlet" target="_blank">servlet</a> </em>corriente y moliente que escribe HTML directamente en  la <em>HttpServletResponse</em> para ir mostrando los resultados del renombrado o de los errores del  mismo por navegador y facilitar la comprobación  del correcto  funcionamiento de la aplicación.</p>
<p style="text-align: justify">Llama a un EJB llamado <em>Renombrador.java</em> que es una clase absurda. lamentable y claramente prescindible pero, que he creado para que veáis que un EJB puede ser cualquier cosa a la que le claves la anotación correspondiente. Renombrador se limitará a devolver un nuevo nombre para el cliente que estará compuesto con los milisegundos de la fecha del sistema (sí, lo di todo por destacar al menos en originalidad).</p>
<p style="text-align: justify">Una vez que haya obtenido el nuevo nombre para el cliente, se invocará el método renombra del EJB <em>ActualizaCliente.java</em> que, sorprenderos, actualizará el nombre del cliente.</p>
<div id="gist-421028" class="gist">
  
  
    
            

      <div class="gist-file">
        <div class="gist-data gist-syntax">
          
          
          
            <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">six</span><span class="o">.</span><span class="na">test</span><span class="o">;</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="kn">import</span> <span class="nn">java.io.IOException</span><span class="o">;</span></div><div class='line' id='LC4'><span class="kn">import</span> <span class="nn">java.io.PrintWriter</span><span class="o">;</span></div><div class='line' id='LC5'><span class="kn">import</span> <span class="nn">javax.ejb.EJB</span><span class="o">;</span></div><div class='line' id='LC6'><span class="kn">import</span> <span class="nn">javax.servlet.ServletException</span><span class="o">;</span></div><div class='line' id='LC7'><span class="kn">import</span> <span class="nn">javax.servlet.annotation.WebServlet</span><span class="o">;</span></div><div class='line' id='LC8'><span class="kn">import</span> <span class="nn">javax.servlet.http.HttpServlet</span><span class="o">;</span></div><div class='line' id='LC9'><span class="kn">import</span> <span class="nn">javax.servlet.http.HttpServletRequest</span><span class="o">;</span></div><div class='line' id='LC10'><span class="kn">import</span> <span class="nn">javax.servlet.http.HttpServletResponse</span><span class="o">;</span></div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'><span class="cm">/**</span></div><div class='line' id='LC13'><span class="cm"> * Servlet de todo a 100 que sirve como ruinosa fachada para nuestros EJBs</span></div><div class='line' id='LC14'><span class="cm"> * @author McGyver</span></div><div class='line' id='LC15'><span class="cm"> */</span></div><div class='line' id='LC16'><span class="nd">@WebServlet</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"RenombraServlet"</span><span class="o">,</span> <span class="n">urlPatterns</span> <span class="o">=</span> <span class="o">{</span><span class="s">"/RenombraServlet"</span><span class="o">})</span></div><div class='line' id='LC17'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">RenombraServlet</span> <span class="kd">extends</span> <span class="n">HttpServlet</span> <span class="o">{</span></div><div class='line' id='LC18'><br/></div><div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@EJB</span></div><div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="n">Renombrador</span> <span class="n">bean</span><span class="o">;</span></div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@EJB</span></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="n">ActualizaCliente</span> <span class="n">session</span><span class="o">;</span></div><div class='line' id='LC23'><br/></div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="cm">/** </span></div><div class='line' id='LC25'><span class="cm">     * Procesa peticiones HTTP de tipo &lt;code&gt;GET&lt;/code&gt; y &lt;code&gt;POST&lt;/code&gt;.</span></div><div class='line' id='LC26'><span class="cm">     * @param request Servlet request</span></div><div class='line' id='LC27'><span class="cm">     * @param response Servlet response</span></div><div class='line' id='LC28'><span class="cm">     * @throws ServletException si existe algún error en el funcionamiento del Servlet</span></div><div class='line' id='LC29'><span class="cm">     * @throws IOException si existe algún error de escritura/lectura</span></div><div class='line' id='LC30'><span class="cm">     */</span></div><div class='line' id='LC31'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">processRequest</span><span class="o">(</span><span class="n">HttpServletRequest</span> <span class="n">request</span><span class="o">,</span> <span class="n">HttpServletResponse</span> <span class="n">response</span><span class="o">)</span></div><div class='line' id='LC32'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">throws</span> <span class="n">ServletException</span><span class="o">,</span> <span class="n">IOException</span> <span class="o">{</span></div><div class='line' id='LC33'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">response</span><span class="o">.</span><span class="na">setContentType</span><span class="o">(</span><span class="s">"text/html;charset=UTF-8"</span><span class="o">);</span></div><div class='line' id='LC34'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">PrintWriter</span> <span class="n">out</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="na">getWriter</span><span class="o">();</span></div><div class='line' id='LC35'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">try</span> <span class="o">{</span></div><div class='line' id='LC36'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">String</span> <span class="n">nuevo_nombre</span> <span class="o">=</span> <span class="n">bean</span><span class="o">.</span><span class="na">renombra</span><span class="o">();</span></div><div class='line' id='LC37'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='line' id='LC38'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Este operador ternario esta dedicado, con amor, a Xavi Gost (@XaV1uzz)</span></div><div class='line' id='LC39'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kt">int</span> <span class="n">tipoBloqueo</span> <span class="o">=</span></div><div class='line' id='LC40'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">esUnNumero</span><span class="o">(</span><span class="n">request</span><span class="o">.</span><span class="na">getParameter</span><span class="o">(</span><span class="s">"lock"</span><span class="o">))</span> <span class="o">?</span></div><div class='line' id='LC41'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">Integer</span><span class="o">.</span><span class="na">parseInt</span><span class="o">(</span><span class="n">request</span><span class="o">.</span><span class="na">getParameter</span><span class="o">(</span><span class="s">"lock"</span><span class="o">))</span> <span class="o">:</span> <span class="mi">0</span><span class="o">;</span></div><div class='line' id='LC42'><br/></div><div class='line' id='LC43'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"&lt;html&gt;"</span><span class="o">);</span></div><div class='line' id='LC44'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"&lt;head&gt;"</span><span class="o">);</span></div><div class='line' id='LC45'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"&lt;title&gt;Renombrando a un Cliente&lt;/title&gt;"</span><span class="o">);</span></div><div class='line' id='LC46'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"&lt;/head&gt;"</span><span class="o">);</span></div><div class='line' id='LC47'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"&lt;body&gt;"</span><span class="o">);</span></div><div class='line' id='LC48'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"&lt;h1&gt;Servlet "</span> <span class="o">+</span> <span class="n">request</span><span class="o">.</span><span class="na">getContextPath</span><span class="o">()</span> <span class="o">+</span> <span class="s">"/RenombraServlet - "</span> <span class="o">+</span> <span class="n">nuevo_nombre</span> <span class="o">+</span> <span class="s">"&lt;/h1&gt;"</span><span class="o">);</span></div><div class='line' id='LC49'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"&lt;br/&gt;"</span><span class="o">);</span></div><div class='line' id='LC50'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">try</span> <span class="o">{</span></div><div class='line' id='LC51'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">session</span><span class="o">.</span><span class="na">renombra</span><span class="o">(</span><span class="n">nuevo_nombre</span><span class="o">,</span> <span class="n">tipoBloqueo</span><span class="o">);</span></div><div class='line' id='LC52'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"&lt;p&gt;Renombrado correcto&lt;/p&gt;"</span><span class="o">);</span></div><div class='line' id='LC53'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">Throwable</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC54'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"&lt;p&gt;Upps !!!: "</span> <span class="o">+</span> <span class="n">e</span> <span class="o">+</span> <span class="s">"&lt;/p&gt;"</span><span class="o">);</span></div><div class='line' id='LC55'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"&lt;p&gt;"</span><span class="o">);</span></div><div class='line' id='LC56'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">(</span><span class="n">out</span><span class="o">);</span></div><div class='line' id='LC57'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"&lt;/p&gt;"</span><span class="o">);</span></div><div class='line' id='LC58'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC59'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"&lt;/body&gt;"</span><span class="o">);</span></div><div class='line' id='LC60'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"&lt;/html&gt;"</span><span class="o">);</span></div><div class='line' id='LC61'><br/></div><div class='line' id='LC62'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span> <span class="k">finally</span> <span class="o">{</span></div><div class='line' id='LC63'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">out</span><span class="o">.</span><span class="na">close</span><span class="o">();</span></div><div class='line' id='LC64'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC65'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC66'><br/></div><div class='line' id='LC67'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="cm">/**</span></div><div class='line' id='LC68'><span class="cm">     * Metodo estupido que he creado para no tener que importar ni una</span></div><div class='line' id='LC69'><span class="cm">     * libreria de Commons de Apache. Reinventing the rueda !!!</span></div><div class='line' id='LC70'><span class="cm">     * @param texto la cadena de texto de la que queremos averiguar si es un número</span></div><div class='line' id='LC71'><span class="cm">     * @return true si el texto expresa un número</span></div><div class='line' id='LC72'><span class="cm">     */</span></div><div class='line' id='LC73'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="kt">boolean</span> <span class="nf">esUnNumero</span><span class="o">(</span><span class="n">String</span> <span class="n">texto</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC74'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kt">boolean</span> <span class="n">respuesta</span> <span class="o">=</span> <span class="kc">false</span><span class="o">;</span></div><div class='line' id='LC75'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">try</span> <span class="o">{</span></div><div class='line' id='LC76'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="o">(</span><span class="n">texto</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC77'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">Integer</span><span class="o">.</span><span class="na">parseInt</span><span class="o">(</span><span class="n">texto</span><span class="o">);</span></div><div class='line' id='LC78'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">respuesta</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span></div><div class='line' id='LC79'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC80'><br/></div><div class='line' id='LC81'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">NumberFormatException</span> <span class="n">ex</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC82'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Este catch vacio se vende como espacio patrocinado</span></div><div class='line' id='LC83'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Anunciante, si quiere exponer sus productos aquí</span></div><div class='line' id='LC84'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// contacte con david@sixservix.com</span></div><div class='line' id='LC85'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC86'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">respuesta</span><span class="o">;</span></div><div class='line' id='LC87'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC88'><br/></div><div class='line' id='LC89'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// &lt;editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."&gt;</span></div><div class='line' id='LC90'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="cm">/** </span></div><div class='line' id='LC91'><span class="cm">     * Handles the HTTP &lt;code&gt;GET&lt;/code&gt; method.</span></div><div class='line' id='LC92'><span class="cm">     * @param request servlet request</span></div><div class='line' id='LC93'><span class="cm">     * @param response servlet response</span></div><div class='line' id='LC94'><span class="cm">     * @throws ServletException if a servlet-specific error occurs</span></div><div class='line' id='LC95'><span class="cm">     * @throws IOException if an I/O error occurs</span></div><div class='line' id='LC96'><span class="cm">     */</span></div><div class='line' id='LC97'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@Override</span></div><div class='line' id='LC98'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">doGet</span><span class="o">(</span><span class="n">HttpServletRequest</span> <span class="n">request</span><span class="o">,</span> <span class="n">HttpServletResponse</span> <span class="n">response</span><span class="o">)</span></div><div class='line' id='LC99'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">throws</span> <span class="n">ServletException</span><span class="o">,</span> <span class="n">IOException</span> <span class="o">{</span></div><div class='line' id='LC100'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">processRequest</span><span class="o">(</span><span class="n">request</span><span class="o">,</span> <span class="n">response</span><span class="o">);</span></div><div class='line' id='LC101'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC102'><br/></div><div class='line' id='LC103'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="cm">/** </span></div><div class='line' id='LC104'><span class="cm">     * Handles the HTTP &lt;code&gt;POST&lt;/code&gt; method.</span></div><div class='line' id='LC105'><span class="cm">     * @param request servlet request</span></div><div class='line' id='LC106'><span class="cm">     * @param response servlet response</span></div><div class='line' id='LC107'><span class="cm">     * @throws ServletException if a servlet-specific error occurs</span></div><div class='line' id='LC108'><span class="cm">     * @throws IOException if an I/O error occurs</span></div><div class='line' id='LC109'><span class="cm">     */</span></div><div class='line' id='LC110'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@Override</span></div><div class='line' id='LC111'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">doPost</span><span class="o">(</span><span class="n">HttpServletRequest</span> <span class="n">request</span><span class="o">,</span> <span class="n">HttpServletResponse</span> <span class="n">response</span><span class="o">)</span></div><div class='line' id='LC112'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">throws</span> <span class="n">ServletException</span><span class="o">,</span> <span class="n">IOException</span> <span class="o">{</span></div><div class='line' id='LC113'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">processRequest</span><span class="o">(</span><span class="n">request</span><span class="o">,</span> <span class="n">response</span><span class="o">);</span></div><div class='line' id='LC114'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC115'><br/></div><div class='line' id='LC116'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="cm">/** </span></div><div class='line' id='LC117'><span class="cm">     * Returns a short description of the servlet.</span></div><div class='line' id='LC118'><span class="cm">     * @return a String containing servlet description</span></div><div class='line' id='LC119'><span class="cm">     */</span></div><div class='line' id='LC120'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@Override</span></div><div class='line' id='LC121'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="n">String</span> <span class="nf">getServletInfo</span><span class="o">()</span> <span class="o">{</span></div><div class='line' id='LC122'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="s">"Short description"</span><span class="o">;</span></div><div class='line' id='LC123'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span><span class="c1">// &lt;/editor-fold&gt;</span></div><div class='line' id='LC124'><span class="o">}</span></div></pre></div>
          
        </div>

        
      </div>
    
  
</div>

<p style="text-align: justify">El <strong><span style="text-decoration: underline">sofisticadísimo renombrador</span></strong>:</p>
<div id="gist-421063" class="gist">
  
  
    
            

      <div class="gist-file">
        <div class="gist-data gist-syntax">
          
          
          
            <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">six</span><span class="o">.</span><span class="na">test</span><span class="o">;</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="kn">import</span> <span class="nn">javax.ejb.Stateless</span><span class="o">;</span></div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="cm">/**</span></div><div class='line' id='LC6'><span class="cm"> * Esta clase es tan tonta que me da verguenza</span></div><div class='line' id='LC7'><span class="cm"> * @author david</span></div><div class='line' id='LC8'><span class="cm"> */</span></div><div class='line' id='LC9'><span class="nd">@Stateless</span></div><div class='line' id='LC10'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Renombrador</span> <span class="o">{</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="n">String</span> <span class="nf">renombra</span><span class="o">(){</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="s">"Nuevo nombre del Cliente: "</span> <span class="o">+</span> <span class="n">System</span><span class="o">.</span><span class="na">currentTimeMillis</span><span class="o">();</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC14'><span class="o">}</span></div></pre></div>
          
        </div>

        
      </div>
    
  
</div>

<p style="text-align: justify">
<h3 style="text-align: justify">2. EL EJB ACTUALIZADOR: BLOQUEOS</h3>
<p style="text-align: justify">El EJB <em>ActualizaCliente.java</em> contiene todo lo que necesitáis saber para crear bloqueos optimistas, pesimistas con NOWAIT y pesimistas con un WAIT determinado.</p>
<p style="text-align: justify">El método principal es <em><strong>renombra</strong>(String nombre, int tipoBloqueo)</em> y, a partir de ahí, podéis ver todo el proceso.</p>
<p style="text-align: justify">Lo primero que se hace en el método es invocar al método secundario <em><strong>getQuery</strong>(int tipoBloqueo)</em> que devolverá una <a href="http://www.jpox.org/docs/1_2/jpa/query.html" target="_blank">Query</a> con el tipo de bloqueo seleccionado:</p>
<ul style="text-align: justify">
<li>Si habéis invocado a <em>RenombraServlet.java </em>sin parámetros o con el parámetro <em>lock </em>con <strong>valor 0</strong>, estaréis creando una Query con <strong>bloqueos optimistas</strong> (te deja consultar una tupla de una tabla de base de datos y sólo te provocará error si actualizas esa tupla después de que haya sido actualizada previamente por otra transacción entre el momento en el que consultaste la tupla y actualizaste -error en <strong>em.flush()</strong>-)</li>
<li>Si habéis invocado a <em>RenombraServlet.java </em>con el  parámetro <em>lock </em>con<strong> valor 1</strong>, estaréis creando una Query con <strong>bloqueos pesimistas NO WAIT</strong><strong> </strong>o &#8220;sin espera&#8221; (sólo permite que una transacción consulte una tupla determinada de una tabla de base de  datos y lanzará error si intentas consultar la misma tupla antes de que acabe la primera transacción -error en <strong>q.getSingleResult()</strong>-)</li>
<li>Si habéis invocado a <em>RenombraServlet.java </em>con el  parámetro <em>lock </em>con <strong>valor 2</strong>, estaréis creando una Query con <strong>bloqueos pesimistas WAIT</strong><strong> </strong>o &#8220;con espera&#8221;<strong> </strong> (sólo permite que una  transacción consulte una tupla determinada de una tabla de base de   datos y lanzará error si intentas consultar la misma tupla antes de  que acabe la primera transacción y<span style="text-decoration: underline"> en  <em>n</em> segundos no finaliza la misma</span> -error en <strong>q.getSingleResult()</strong>-). En esta aplicación, la espera o <em>WAIT</em> está configurada para durar dos segundos.</li>
</ul>
<p style="text-align: justify">Podéis probar los bloqueos depurando la aplicación y accediendo a la misma desde dos navegadores. Si ponéis un punto de interrupción justo en la línea donde se invoca <strong>q.getSingleResult()</strong><strong>, </strong>con un primer hilo invocáis el método y pausáis la aplicación, cuando hagáis lo mismo con el segundo hilo veréis como la aplicación lanza un error si habéis utilizado un bloqueo pesimista -inmediatamente si es de tipo NOWAIT y después de <em>n</em> segundos en el caso del WAIT- y como continúa en el caso de que utilicéis los bloqueos optimistas.</p>
<p style="text-align: justify">Poned otro punto de interrupción en la línea <strong>em.flush(),</strong> veréis que el hilo de bloqueo pesimista que consiga llegar hasta dicho punto lo superará sin problemas. Por el contrario, en el caso de los bloqueos optimistas, el primer hilo que invoque el método, persistirá sin problemas y el segundo lanzará un OptimisticLockException que os dejará sentados en la silla con cara de asno esloveno.</p>
<div id="gist-421067" class="gist">
  
  
    
            

      <div class="gist-file">
        <div class="gist-data gist-syntax">
          
          
          
            <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">six</span><span class="o">.</span><span class="na">test</span><span class="o">;</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="kn">import</span> <span class="nn">javax.persistence.EntityManager</span><span class="o">;</span></div><div class='line' id='LC4'><span class="kn">import</span> <span class="nn">javax.persistence.Query</span><span class="o">;</span></div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'><span class="kn">import</span> <span class="nn">com.six.model.entity.*</span><span class="o">;</span></div><div class='line' id='LC7'><span class="kn">import</span> <span class="nn">javax.ejb.EJB</span><span class="o">;</span></div><div class='line' id='LC8'><span class="kn">import</span> <span class="nn">javax.ejb.Stateless</span><span class="o">;</span></div><div class='line' id='LC9'><span class="kn">import</span> <span class="nn">javax.ejb.TransactionAttribute</span><span class="o">;</span></div><div class='line' id='LC10'><span class="kn">import</span> <span class="nn">javax.ejb.TransactionAttributeType</span><span class="o">;</span></div><div class='line' id='LC11'><span class="kn">import</span> <span class="nn">javax.persistence.NoResultException</span><span class="o">;</span></div><div class='line' id='LC12'><span class="kn">import</span> <span class="nn">javax.persistence.PersistenceContext</span><span class="o">;</span></div><div class='line' id='LC13'><span class="kn">import</span> <span class="nn">org.eclipse.persistence.config.PessimisticLock</span><span class="o">;</span></div><div class='line' id='LC14'><span class="kn">import</span> <span class="nn">org.eclipse.persistence.config.QueryHints</span><span class="o">;</span></div><div class='line' id='LC15'><br/></div><div class='line' id='LC16'><span class="cm">/**</span></div><div class='line' id='LC17'><span class="cm"> * @author Spiderman</span></div><div class='line' id='LC18'><span class="cm"> */</span></div><div class='line' id='LC19'><span class="nd">@Stateless</span></div><div class='line' id='LC20'><span class="nd">@TransactionAttribute</span><span class="o">(</span><span class="n">TransactionAttributeType</span><span class="o">.</span><span class="na">REQUIRED</span><span class="o">)</span></div><div class='line' id='LC21'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ActualizaCliente</span> <span class="o">{</span></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="n">CUSTOMER_ID</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span></div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="n">SECONDS_WAIT</span> <span class="o">=</span> <span class="mi">2</span><span class="o">;</span></div><div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@PersistenceContext</span></div><div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="n">EntityManager</span> <span class="n">em</span><span class="o">;</span></div><div class='line' id='LC28'><br/></div><div class='line' id='LC29'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@EJB</span></div><div class='line' id='LC30'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="n">NOActualizaCliente</span> <span class="n">sc2</span><span class="o">;</span></div><div class='line' id='LC31'><br/></div><div class='line' id='LC32'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="nf">ActualizaCliente</span><span class="o">()</span> <span class="o">{</span>        </div><div class='line' id='LC33'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC34'><br/></div><div class='line' id='LC35'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="kt">void</span> <span class="nf">renombra</span><span class="o">(</span><span class="n">String</span> <span class="n">nombre</span><span class="o">,</span> <span class="kt">int</span> <span class="n">tipoBloqueo</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Throwable</span> <span class="o">{</span></div><div class='line' id='LC36'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='line' id='LC37'><br/></div><div class='line' id='LC38'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">try</span> <span class="o">{</span></div><div class='line' id='LC39'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">Query</span> <span class="n">q</span> <span class="o">=</span> <span class="n">getQuery</span><span class="o">(</span><span class="n">tipoBloqueo</span><span class="o">);</span></div><div class='line' id='LC40'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">Customer</span> <span class="n">c</span> <span class="o">=</span> <span class="o">(</span><span class="n">Customer</span><span class="o">)</span> <span class="n">q</span><span class="o">.</span><span class="na">getSingleResult</span><span class="o">();</span></div><div class='line' id='LC41'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"El nombre del Cliente es: "</span> <span class="o">+</span> <span class="n">c</span><span class="o">.</span><span class="na">getName</span><span class="o">());</span></div><div class='line' id='LC42'><br/></div><div class='line' id='LC43'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="o">(</span><span class="n">c</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC44'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Crea un nuevo Cliente</span></div><div class='line' id='LC45'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">Customer</span> <span class="n">customer0</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Customer</span><span class="o">();</span></div><div class='line' id='LC46'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">customer0</span><span class="o">.</span><span class="na">setId</span><span class="o">(</span><span class="n">CUSTOMER_ID</span><span class="o">);</span></div><div class='line' id='LC47'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">customer0</span><span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="s">"Jose María Arranz"</span><span class="o">);</span></div><div class='line' id='LC48'><br/></div><div class='line' id='LC49'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Persiste el cliente</span></div><div class='line' id='LC50'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">em</span><span class="o">.</span><span class="na">persist</span><span class="o">(</span><span class="n">customer0</span><span class="o">);</span></div><div class='line' id='LC51'><br/></div><div class='line' id='LC52'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Crea 2 nuevas ordenes</span></div><div class='line' id='LC53'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">Order</span> <span class="n">order1</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Order</span><span class="o">();</span></div><div class='line' id='LC54'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">order1</span><span class="o">.</span><span class="na">setId</span><span class="o">(</span><span class="mi">100</span><span class="o">);</span></div><div class='line' id='LC55'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">order1</span><span class="o">.</span><span class="na">setAddress</span><span class="o">(</span><span class="s">"C/ACDC 14. Leganes, España"</span><span class="o">);</span></div><div class='line' id='LC56'><br/></div><div class='line' id='LC57'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">Order</span> <span class="n">order2</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Order</span><span class="o">();</span></div><div class='line' id='LC58'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">order2</span><span class="o">.</span><span class="na">setId</span><span class="o">(</span><span class="mi">200</span><span class="o">);</span></div><div class='line' id='LC59'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">order2</span><span class="o">.</span><span class="na">setAddress</span><span class="o">(</span><span class="s">"129 James Gosling Ave. San Francisco, USA"</span><span class="o">);</span></div><div class='line' id='LC60'><br/></div><div class='line' id='LC61'><br/></div><div class='line' id='LC62'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="cm">/**</span></div><div class='line' id='LC63'><span class="cm">                 * Asociación de las ordenes con el cliente. La asociación</span></div><div class='line' id='LC64'><span class="cm">                 * debe estar configurada en ambos lados de la relación: en</span></div><div class='line' id='LC65'><span class="cm">                 * la parte del Cliente para que las ordenes se persistan</span></div><div class='line' id='LC66'><span class="cm">                 * cuando la transaccion se comitee, y en el lado de las</span></div><div class='line' id='LC67'><span class="cm">                 * ordenes para configurar la relación.</span></div><div class='line' id='LC68'><span class="cm">                 */</span></div><div class='line' id='LC69'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">customer0</span><span class="o">.</span><span class="na">getOrders</span><span class="o">().</span><span class="na">add</span><span class="o">(</span><span class="n">order1</span><span class="o">);</span></div><div class='line' id='LC70'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">order1</span><span class="o">.</span><span class="na">setCustomer</span><span class="o">(</span><span class="n">customer0</span><span class="o">);</span></div><div class='line' id='LC71'><br/></div><div class='line' id='LC72'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">customer0</span><span class="o">.</span><span class="na">getOrders</span><span class="o">().</span><span class="na">add</span><span class="o">(</span><span class="n">order2</span><span class="o">);</span></div><div class='line' id='LC73'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">order2</span><span class="o">.</span><span class="na">setCustomer</span><span class="o">(</span><span class="n">customer0</span><span class="o">);</span></div><div class='line' id='LC74'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span> <span class="k">else</span> <span class="o">{</span></div><div class='line' id='LC75'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">sc2</span><span class="o">.</span><span class="na">renombra</span><span class="o">(</span><span class="n">c</span><span class="o">);</span></div><div class='line' id='LC76'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">c</span><span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="n">nombre</span><span class="o">);</span></div><div class='line' id='LC77'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">em</span><span class="o">.</span><span class="na">flush</span><span class="o">();</span></div><div class='line' id='LC78'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"El nombre del Cliente es: "</span> <span class="o">+</span> <span class="n">c</span><span class="o">.</span><span class="na">getName</span><span class="o">());</span></div><div class='line' id='LC79'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC80'><br/></div><div class='line' id='LC81'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">Throwable</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC82'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"ERROR: "</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="na">getMessage</span><span class="o">());</span></div><div class='line' id='LC83'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">throw</span> <span class="n">e</span><span class="o">;</span></div><div class='line' id='LC84'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC85'><br/></div><div class='line' id='LC86'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC87'><br/></div><div class='line' id='LC88'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="n">Query</span> <span class="nf">getQuery</span><span class="o">(</span><span class="kt">int</span> <span class="n">tipoBloqueo</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC89'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='line' id='LC90'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Por defecto, se utiliza el bloqueo optimista.</span></div><div class='line' id='LC91'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Si se actualiza despues de otra actualización OptimisticLock Exception</span></div><div class='line' id='LC92'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">Query</span> <span class="n">q</span> <span class="o">=</span> <span class="n">em</span><span class="o">.</span><span class="na">createNamedQuery</span><span class="o">(</span><span class="s">"Customer.findById"</span><span class="o">);</span></div><div class='line' id='LC93'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">q</span><span class="o">.</span><span class="na">setParameter</span><span class="o">(</span><span class="s">"id"</span><span class="o">,</span> <span class="n">CUSTOMER_ID</span><span class="o">);</span></div><div class='line' id='LC94'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">switch</span><span class="o">(</span><span class="n">tipoBloqueo</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC95'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">case</span> <span class="mi">1</span><span class="o">:</span></div><div class='line' id='LC96'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Bloqueo pesimista con no wait</span></div><div class='line' id='LC97'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">q</span><span class="o">.</span><span class="na">setHint</span><span class="o">(</span><span class="n">QueryHints</span><span class="o">.</span><span class="na">PESSIMISTIC_LOCK</span><span class="o">,</span> <span class="n">PessimisticLock</span><span class="o">.</span><span class="na">LockNoWait</span><span class="o">);</span></div><div class='line' id='LC98'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Bloqueos Pesimistas con NOWAIT !!!"</span><span class="o">);</span></div><div class='line' id='LC99'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">break</span><span class="o">;</span></div><div class='line' id='LC100'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">case</span> <span class="mi">2</span><span class="o">:</span></div><div class='line' id='LC101'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">//Bloqueo pesimista con wait de 2 segundos</span></div><div class='line' id='LC102'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">q</span><span class="o">.</span><span class="na">setHint</span><span class="o">(</span><span class="n">QueryHints</span><span class="o">.</span><span class="na">PESSIMISTIC_LOCK</span><span class="o">,</span> <span class="n">PessimisticLock</span><span class="o">.</span><span class="na">Lock</span><span class="o">);</span></div><div class='line' id='LC103'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">q</span><span class="o">.</span><span class="na">setHint</span><span class="o">(</span><span class="n">QueryHints</span><span class="o">.</span><span class="na">JDBC_TIMEOUT</span><span class="o">,</span> <span class="n">SECONDS_WAIT</span><span class="o">);</span></div><div class='line' id='LC104'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Bloqueos Pesimistas con WAIT de "</span> <span class="o">+</span> <span class="n">SECONDS_WAIT</span> <span class="o">+</span> <span class="s">" segundos !!!"</span><span class="o">);</span></div><div class='line' id='LC105'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">break</span><span class="o">;</span></div><div class='line' id='LC106'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">default</span><span class="o">:</span></div><div class='line' id='LC107'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Bloqueos Optimistas !!!"</span><span class="o">);</span></div><div class='line' id='LC108'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">break</span><span class="o">;</span></div><div class='line' id='LC109'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span>               </div><div class='line' id='LC110'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">q</span><span class="o">;</span></div><div class='line' id='LC111'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC112'><br/></div><div class='line' id='LC113'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="n">Customer</span> <span class="nf">findCustomer</span><span class="o">(</span><span class="n">Integer</span> <span class="n">id</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC114'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">Customer</span> <span class="n">customer</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span></div><div class='line' id='LC115'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">Query</span> <span class="n">q</span> <span class="o">=</span> <span class="n">em</span><span class="o">.</span><span class="na">createQuery</span><span class="o">(</span><span class="s">"select c from Customer c where c.id = :id"</span><span class="o">);</span></div><div class='line' id='LC116'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">q</span><span class="o">.</span><span class="na">setParameter</span><span class="o">(</span><span class="s">"id"</span><span class="o">,</span> <span class="n">id</span><span class="o">);</span></div><div class='line' id='LC117'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">try</span> <span class="o">{</span></div><div class='line' id='LC118'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">customer</span> <span class="o">=</span> <span class="o">(</span><span class="n">Customer</span><span class="o">)</span> <span class="n">q</span><span class="o">.</span><span class="na">getSingleResult</span><span class="o">();</span></div><div class='line' id='LC119'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">NoResultException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC120'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC121'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">customer</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">?</span> <span class="s">"Customer nulo "</span> <span class="o">:</span> <span class="s">"Customer "</span> <span class="o">+</span> <span class="n">customer</span><span class="o">.</span><span class="na">getName</span><span class="o">());</span></div><div class='line' id='LC122'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">customer</span><span class="o">;</span></div><div class='line' id='LC123'><br/></div><div class='line' id='LC124'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC125'><br/></div><div class='line' id='LC126'><span class="o">}</span></div></pre></div>
          
        </div>

        
      </div>
    
  
</div>

<h3 style="text-align: justify">3. EL EJB NO ACTUALIZADOR: TRANSACCIONES</h3>
<p style="text-align: justify">Si con la clase <em>ActualizaCliente.java</em> hemos aprendido como se utilizan bloqueos de todo tipo con EJB3.1 y el comportamiento de cada uno de los mismos, con el EJB <em>NOActualizaCliente.java</em> comprenderemos cómo se manejan transacciones a través de invocaciones e invocaciones de EJBs.</p>
<p style="text-align: justify">Los EJBs nos proporcionan una transaccionalidad inmediata en cada uno de sus métodos, sin embargo, puede que tengamos lógica de negocio que necesite ser invocada con transaccionalidad dispersada por varias clases y métodos. ¿Cómo podemos conservar nuestras preciosas <a href="http://es.wikipedia.org/wiki/ACID" target="_blank">transacciones ACID</a> a través de toda la maraña de invocaciones?</p>
<p style="text-align: justify">La sencillez de gestión de transacciones con JPA es inversamente proporcional a la corrección con que la gente las utiliza.</p>
<p style="text-align: justify">La clase <em>NOActualizaCliente.java </em>se llama así porque realmente <span style="text-decoration: underline">jamás actualizará la base de datos</span>. ¿Por qué, si se modifica un objeto mapeado directamente con una tupla en una tabla, y se persiste mediante <strong>em.persist()</strong> y <strong>em.flush()</strong>? Pues muy sencillo: por la configuración de transacciones dentro de la clase.</p>
<p style="text-align: justify">Si os fijáis bien, la clase se declara con una configuración global de transacciones:</p>
<pre style="text-align: justify">
<div id="LC17">@TransactionAttribute(TransactionAttributeType.REQUIRED)</div>
</pre>
<p style="text-align: justify">Esta configuración se aplica a TODOS los métodos de la clase y, básicamente implica dos cosas:</p>
<ul style="text-align: justify">
<li>Si el método se invoca dentro de una transacción, se utiliza dicha transacción</li>
<li>Si el método no se invoca dentro de una transacción, se crea una que se cerrará con la finalización del mismo</li>
</ul>
<p style="text-align: justify">Sin embargo, puede que queramos que nuestro método tenga una configuración de transaccionalidad especifica y diferente del resto de los métodos de la clase ¿Cómo podemos conseguirlo? Proporcionando dicha configuración especifica mediante la misma anotación, pero a nivel de método:</p>
<pre style="text-align: justify"> @TransactionAttribute(TransactionAttributeType.MANDATORY)</pre>
<p style="text-align: justify">
<p style="text-align: justify">La configuración de transaccionalidad MANDATORY es ligeramente distinta a la de REQUIRED porque esta configuración implica que el método debe ser invocado dentro de una transacción y, si no es así, se lanza un error.  Si intentaramos invocar este método directamente desde nuestro Servlet, el error que obtendrías sería de proporciones bíblicas.</p>
<p style="text-align: justify">¿Quiere decir esto que no podremos invocarlo jamás desde un servlet? Pues&#8230; no. Podemos <a href="http://www.datanucleus.org/products/accessplatform_1_1/jpa/transactions.html" target="_blank">crear transacciones de forma manual</a>, aunque seguro, seguro, seguro que el contenedor las gestiona mejor que nosotros&#8230; o al menos que yo.</p>
<p style="text-align: justify">Al utilizar la configuración MANDATORY me he asegurado que la lógica de este método siempre sea invocada dentro de una transacción. Como el método <strong>renombra()</strong> de <em>NOActualizaCliente.java </em>se invoca desde el método <strong>renombra()</strong> de la clase <em>ActualizaCliente.java </em>e, inmediatamente después, se vuelve a actualizar desde ese método el objeto<em> </em>actualizado por el primero, <span style="text-decoration: underline">la actualización de la clase <em>NOActualizaCliente.java </em>jamás se hará efectiva en la base de datos</span>.<em> </em></p>
<p style="text-align: justify">¿Por qué? <span style="text-decoration: underline">Porque estamos dentro de una transacción</span> y, hasta que la misma no finalice, no se harán efectivos ninguno de los cambios realizados a nivel de código. La finalización del método <strong>renombra()</strong> de <em>NOActualizaCliente.java</em> no implica la finalización de ninguna transacción y, por tanto, no implica persistencia de los datos.</p>
<div id="gist-421069" class="gist">
  
  
    
            

      <div class="gist-file">
        <div class="gist-data gist-syntax">
          
          
          
            <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">six</span><span class="o">.</span><span class="na">test</span><span class="o">;</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="kn">import</span> <span class="nn">javax.persistence.EntityManager</span><span class="o">;</span></div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="kn">import</span> <span class="nn">com.six.model.entity.*</span><span class="o">;</span></div><div class='line' id='LC6'><span class="kn">import</span> <span class="nn">javax.ejb.Stateless</span><span class="o">;</span></div><div class='line' id='LC7'><span class="kn">import</span> <span class="nn">javax.ejb.TransactionAttribute</span><span class="o">;</span></div><div class='line' id='LC8'><span class="kn">import</span> <span class="nn">javax.ejb.TransactionAttributeType</span><span class="o">;</span></div><div class='line' id='LC9'><span class="kn">import</span> <span class="nn">javax.persistence.PersistenceContext</span><span class="o">;</span></div><div class='line' id='LC10'><br/></div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'><span class="cm">/**</span></div><div class='line' id='LC13'><span class="cm"> * @author Hulk</span></div><div class='line' id='LC14'><span class="cm"> */</span></div><div class='line' id='LC15'><span class="nd">@Stateless</span></div><div class='line' id='LC16'><span class="nd">@TransactionAttribute</span><span class="o">(</span><span class="n">TransactionAttributeType</span><span class="o">.</span><span class="na">REQUIRED</span><span class="o">)</span></div><div class='line' id='LC17'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">NOActualizaCliente</span> <span class="o">{</span></div><div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@PersistenceContext</span></div><div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="n">EntityManager</span> <span class="n">em</span><span class="o">;</span></div><div class='line' id='LC21'><br/></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="nf">NOActualizaCliente</span><span class="o">()</span> <span class="o">{</span>        </div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC24'><br/></div><div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="cm">/**</span></div><div class='line' id='LC26'><span class="cm">     * Este método sirve para comprobar que las transacciones </span></div><div class='line' id='LC27'><span class="cm">     * funcionan con llamadas a varios métodos puesto que hasta que el método</span></div><div class='line' id='LC28'><span class="cm">     * que la invoca no hace el flush, los cambios no llegan a Base de Datos</span></div><div class='line' id='LC29'><span class="cm">     * @param c un Cliente de toda la vida</span></div><div class='line' id='LC30'><span class="cm">     */</span></div><div class='line' id='LC31'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@TransactionAttribute</span><span class="o">(</span><span class="n">TransactionAttributeType</span><span class="o">.</span><span class="na">MANDATORY</span><span class="o">)</span></div><div class='line' id='LC32'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="kt">void</span> <span class="nf">renombra</span><span class="o">(</span><span class="n">Customer</span> <span class="n">c</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC33'><br/></div><div class='line' id='LC34'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">try</span> <span class="o">{</span></div><div class='line' id='LC35'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">c</span><span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="s">"Esto JAMÁS deberia ir a base de datos"</span><span class="o">);</span></div><div class='line' id='LC36'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">em</span><span class="o">.</span><span class="na">persist</span><span class="o">(</span><span class="n">c</span><span class="o">);</span></div><div class='line' id='LC37'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">em</span><span class="o">.</span><span class="na">flush</span><span class="o">();</span></div><div class='line' id='LC38'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"El nombre del Cliente es: "</span> <span class="o">+</span> <span class="n">c</span><span class="o">.</span><span class="na">getName</span><span class="o">());</span></div><div class='line' id='LC39'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">Throwable</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC40'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"ERROR: "</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="na">getMessage</span><span class="o">());</span></div><div class='line' id='LC41'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC42'><br/></div><div class='line' id='LC43'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC44'>&nbsp;</div><div class='line' id='LC45'><span class="o">}</span></div></pre></div>
          
        </div>

        
      </div>
    
  
</div>

<p style="text-align: justify">Para finalizar, os copio los EJBs de tipo <em>Entity</em> que soportan el mapeo entre los objetos de la aplicación y la base de datos.</p>
<p style="text-align: justify">Customer:</p>
<p style="text-align: justify"><div id="gist-421145" class="gist">
  
  
    
            

      <div class="gist-file">
        <div class="gist-data gist-syntax">
          
          
          
            <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">six</span><span class="o">.</span><span class="na">model</span><span class="o">.</span><span class="na">entity</span><span class="o">;</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="kn">import</span> <span class="nn">java.io.Serializable</span><span class="o">;</span></div><div class='line' id='LC4'><span class="kn">import</span> <span class="nn">javax.persistence.*</span><span class="o">;</span></div><div class='line' id='LC5'><span class="kn">import</span> <span class="nn">static</span> <span class="n">javax</span><span class="o">.</span><span class="na">persistence</span><span class="o">.</span><span class="na">CascadeType</span><span class="o">.*;</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'><span class="kn">import</span> <span class="nn">java.util.Collection</span><span class="o">;</span></div><div class='line' id='LC8'><span class="kn">import</span> <span class="nn">java.util.ArrayList</span><span class="o">;</span></div><div class='line' id='LC9'><br/></div><div class='line' id='LC10'><br/></div><div class='line' id='LC11'><span class="nd">@Entity</span></div><div class='line' id='LC12'><span class="nd">@NamedQueries</span><span class="o">({</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@NamedQuery</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"Customer.findById"</span><span class="o">,</span> <span class="n">query</span> <span class="o">=</span> <span class="s">"SELECT u FROM Customer u WHERE u.id = :id"</span><span class="o">)})</span></div><div class='line' id='LC14'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Customer</span> <span class="kd">implements</span> <span class="n">Serializable</span> <span class="o">{</span></div><div class='line' id='LC15'><br/></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="kt">int</span> <span class="n">id</span><span class="o">;</span></div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span></div><div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="n">Collection</span><span class="o">&lt;</span><span class="n">Order</span><span class="o">&gt;</span> <span class="n">orders</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ArrayList</span><span class="o">&lt;</span><span class="n">Order</span><span class="o">&gt;();</span></div><div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="kt">int</span> <span class="n">version</span><span class="o">;</span></div><div class='line' id='LC20'><br/></div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@Id</span></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="kt">int</span> <span class="nf">getId</span><span class="o">()</span> <span class="o">{</span></div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">id</span><span class="o">;</span></div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC25'><br/></div><div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setId</span><span class="o">(</span><span class="kt">int</span> <span class="n">id</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="o">.</span><span class="na">id</span> <span class="o">=</span> <span class="n">id</span><span class="o">;</span></div><div class='line' id='LC28'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC29'><br/></div><div class='line' id='LC30'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="n">String</span> <span class="nf">getName</span><span class="o">()</span> <span class="o">{</span></div><div class='line' id='LC31'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">name</span><span class="o">;</span></div><div class='line' id='LC32'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC33'><br/></div><div class='line' id='LC34'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setName</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC35'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span></div><div class='line' id='LC36'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC37'><br/></div><div class='line' id='LC38'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@OneToMany</span><span class="o">(</span><span class="n">cascade</span><span class="o">=</span><span class="n">ALL</span><span class="o">,</span> <span class="n">mappedBy</span><span class="o">=</span><span class="s">"customer"</span><span class="o">)</span></div><div class='line' id='LC39'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="n">Collection</span><span class="o">&lt;</span><span class="n">Order</span><span class="o">&gt;</span> <span class="n">getOrders</span><span class="o">()</span> <span class="o">{</span></div><div class='line' id='LC40'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">orders</span><span class="o">;</span></div><div class='line' id='LC41'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC42'><br/></div><div class='line' id='LC43'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setOrders</span><span class="o">(</span><span class="n">Collection</span><span class="o">&lt;</span><span class="n">Order</span><span class="o">&gt;</span> <span class="n">newValue</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC44'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="o">.</span><span class="na">orders</span> <span class="o">=</span> <span class="n">newValue</span><span class="o">;</span></div><div class='line' id='LC45'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC46'><br/></div><div class='line' id='LC47'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@Version</span></div><div class='line' id='LC48'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="kt">int</span> <span class="nf">getVersion</span><span class="o">()</span> <span class="o">{</span></div><div class='line' id='LC49'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">version</span><span class="o">;</span></div><div class='line' id='LC50'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC51'><br/></div><div class='line' id='LC52'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setVersion</span><span class="o">(</span><span class="kt">int</span> <span class="n">version</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC53'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="o">.</span><span class="na">version</span> <span class="o">=</span> <span class="n">version</span><span class="o">;</span></div><div class='line' id='LC54'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC55'><br/></div><div class='line' id='LC56'><span class="o">}</span></div></pre></div>
          
        </div>

        
      </div>
    
  
</div>
</p>
<p>Order:</p>
<div id="gist-421151" class="gist">
  
  
    
            

      <div class="gist-file">
        <div class="gist-data gist-syntax">
          
          
          
            <div class="highlight"><pre><div class='line' id='LC1'><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">six</span><span class="o">.</span><span class="na">model</span><span class="o">.</span><span class="na">entity</span><span class="o">;</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="kn">import</span> <span class="nn">javax.persistence.*</span><span class="o">;</span></div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="nd">@Entity</span></div><div class='line' id='LC6'><span class="nd">@Table</span><span class="o">(</span><span class="n">name</span><span class="o">=</span><span class="s">"ORDER_TABLE"</span><span class="o">)</span></div><div class='line' id='LC7'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Order</span> <span class="o">{</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="kt">int</span> <span class="n">id</span><span class="o">;</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="n">String</span> <span class="n">address</span><span class="o">;</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">private</span> <span class="n">Customer</span> <span class="n">customer</span><span class="o">;</span></div><div class='line' id='LC12'><br/></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@Id</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@Column</span><span class="o">(</span><span class="n">name</span><span class="o">=</span><span class="s">"ORDER_ID"</span><span class="o">)</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="kt">int</span> <span class="nf">getId</span><span class="o">()</span> <span class="o">{</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">id</span><span class="o">;</span></div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC18'><br/></div><div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setId</span><span class="o">(</span><span class="kt">int</span> <span class="n">id</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="o">.</span><span class="na">id</span> <span class="o">=</span> <span class="n">id</span><span class="o">;</span></div><div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC22'><br/></div><div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@Column</span><span class="o">(</span><span class="n">name</span><span class="o">=</span><span class="s">"SHIPPING_ADDRESS"</span><span class="o">)</span></div><div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="n">String</span> <span class="nf">getAddress</span><span class="o">()</span> <span class="o">{</span></div><div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">address</span><span class="o">;</span></div><div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC27'><br/></div><div class='line' id='LC28'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setAddress</span><span class="o">(</span><span class="n">String</span> <span class="n">address</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC29'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="o">.</span><span class="na">address</span> <span class="o">=</span> <span class="n">address</span><span class="o">;</span></div><div class='line' id='LC30'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC31'><br/></div><div class='line' id='LC32'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@ManyToOne</span><span class="o">()</span></div><div class='line' id='LC33'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nd">@JoinColumn</span><span class="o">(</span><span class="n">name</span><span class="o">=</span><span class="s">"CUSTOMER_ID"</span><span class="o">)</span></div><div class='line' id='LC34'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="n">Customer</span> <span class="nf">getCustomer</span><span class="o">()</span> <span class="o">{</span></div><div class='line' id='LC35'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">customer</span><span class="o">;</span></div><div class='line' id='LC36'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC37'><br/></div><div class='line' id='LC38'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setCustomer</span><span class="o">(</span><span class="n">Customer</span> <span class="n">customer</span><span class="o">)</span> <span class="o">{</span></div><div class='line' id='LC39'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="o">.</span><span class="na">customer</span> <span class="o">=</span> <span class="n">customer</span><span class="o">;</span></div><div class='line' id='LC40'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">}</span></div><div class='line' id='LC41'><span class="o">}</span></div></pre></div>
          
        </div>

        
      </div>
    
  
</div>

<p style="text-align: justify">Espero que después de este tutorial de todo a cien, al menos tengáis claro que SE PUEDEN conseguir bloqueos de todo tipo y transacciones <strong>ACID</strong> con <strong>EJB3.1 </strong>y <strong>JPA2</strong> (recordar, <strong>JPA1 </strong>sólo soportaba las optimistas). Ahora tenéis el poder suficiente para hacer lo que os dé la gana con vuestras transacciones y bloqueos; y, como decía el filósofo más importante del siglo XX, el <strong>Tío Ben</strong> de Peter Parker/Spiderman &#8220;un gran poder implica una gran responsabilidad&#8221;. Espero que todo esto os sea útil y os haya ahorrado algunas horas de I+D.</p>
<p style="text-align: center"><em>Peter, no la cagues con las transacciones&#8230;</em></p>
<p style="text-align: center"><p><a href="http://sixservix.com/blog/david/2010/06/02/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-iii/"><em>Pinche aquí para ver el vídeo</em></a></p></p>
<h3 style="text-align: justify"><span style="color: #339966">DISCLAIMER:</span></h3>
<ul>
<li><strong><span style="color: #339966">Ningún gatito resultó herido en la realización de este tutorial</span></strong></li>
<li><strong><span style="color: #339966">Debo agradecer a <a href="http://plagelao.blogspot.com/" target="_blank">Alberto Peña</a> (aka <a href="http://twitter.com/plagelao" target="_blank">@plagelao</a>) el conocimiento, uso y disfrute de los <a href="http://gist.github.com/" target="_blank">Gist</a> de de <a href="http://github.com/" target="_blank">GitHub</a> con los que se comparte el código de este ejemplo.</span></strong></li>
<li><strong><span style="color: #339966">Si quieres el código de esta aplicación y todos sus ficheros de configuración, mándame un correo y por un módico precio llegaremos a un acuerdo. Si lo pides por favor, puede que te salga gratis (gracias a <a href="http://www.sixservix.com" target="_blank">Sixservix</a>)</span></strong></li>
</ul>
<p style="text-align: justify">


<p>Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/08/24/logging-glassfish/' rel='bookmark' title='Permanent Link: Arquitectura de logging en Glassfish'>Arquitectura de logging en Glassfish</a> <small>Aprende como funciona el sistema de registro o logging en...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/05/12/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-ii/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (II)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (II)</a> <small>Segunda parte del tutorial sobre como utilizar transacciones y bloqueos...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/05/10/transacciones-bloqueos-glassfish-v3-ejb31-jpa2/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (I)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (I)</a> <small>Un sencillo tutorial sobre como utilizar transacciones y bloqueos con...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/06/02/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-iii/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (II)</title>
		<link>http://sixservix.com/blog/david/2010/05/12/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-ii/</link>
		<comments>http://sixservix.com/blog/david/2010/05/12/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-ii/#comments</comments>
		<pubDate>Wed, 12 May 2010 04:50:42 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[EclipseLink]]></category>
		<category><![CDATA[ejb]]></category>
		<category><![CDATA[ejb3.1]]></category>
		<category><![CDATA[glassfish]]></category>
		<category><![CDATA[glassfish v3]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[JPA2]]></category>
		<category><![CDATA[netbeans]]></category>
		<category><![CDATA[persistence unit]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=3055</guid>
		<description><![CDATA[Segunda parte del tutorial sobre como utilizar transacciones y bloqueos con JPA2 en Glassfish v3 con JPA2.


Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/08/24/logging-glassfish/' rel='bookmark' title='Permanent Link: Arquitectura de logging en Glassfish'>Arquitectura de logging en Glassfish</a> <small>Aprende como funciona el sistema de registro o logging en...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/06/02/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-iii/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (III)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (III)</a> <small>Tercera parte del tutorial sobre como utilizar transacciones y bloqueos...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/05/10/transacciones-bloqueos-glassfish-v3-ejb31-jpa2/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (I)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (I)</a> <small>Un sencillo tutorial sobre como utilizar transacciones y bloqueos con...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><span style="color: #888888"><img class="alignleft size-full wp-image-3060" style="margin-right: 10px" src="http://sixservix.com/blog/david/files/2010/05/persistencia2.jpg" alt="persistencia2" width="300" height="225" /><span style="color: #000000">Continuo con mi proyecto de <strong><em>mega-artículo-tutorial-taladro</em></strong> sobre transacciones y bloqueos con <strong>JPA2 </strong>y <strong>EJB 3.1</strong> en <strong>Glassfish v3</strong>.</span></span></p>
<p style="text-align: justify"><span style="color: #888888"><span style="color: #000000">En el <a href="http://sixservix.com/blog/david/2010/05/10/transacciones-bloqueos-glassfish-v3-ejb31-jpa2/" target="_blank">artículo anterior</a>, aprendimos a configurar base de datos y servidor para poder llevar a cabo este tutorial. En esta nueva entrega, aprenderemos a configurar nuestra aplicación para que pueda trabajar con estas tecnologías.</span></span></p>
<h3><span style="color: #888888">3. CREANDO NUESTRO PROYECTO EN EL IDE</span></h3>
<p style="text-align: justify">Yo he utilizado <a href="http://blogultura.com/java/netbeans-6-8-liberado/" target="_blank">Netbeans 6.8</a> como IDE para crear este ejemplo. No porque crea que sea el mejor entorno de trabajo, ni porque sea un <em>fan </em>de los productos de <strong>Oracle/SUN,</strong> sino porque es el que mejor integración nativa trae de serie con <strong>Glassfish v3</strong>. Bajo mi modesta experiencia -y llevo unos cuantos años en esto- <span style="text-decoration: underline">el Servidor de Aplicaciones elegido puede condicionar totalmente vuestra arquitectura</span>; y la integración, gestión y depuración del mismo, la elección de un IDE u otro. <strong>Podéis seguir este tutorial aunque utilicéis otro IDE</strong>, sólo tenéis que adaptar lo que se vaya haciendo a las peculiaridades de vuestro entorno de trabajo.</p>
<p style="text-align: justify">Para crear nuestro proyecto utilizaremos el <em>wizard </em>que se lanza desde la siguiente ruta de menú:</p>
<p style="text-align: justify"><em>File &gt;&gt; New Project &gt;&gt; Java Web &gt;&gt; Web Application</em>.</p>
<p style="text-align: justify">Se desplegará una primera interfaz donde se indicará el nombre del proyecto:</p>
<div id="attachment_3074" class="wp-caption aligncenter" style="width: 310px"><a href="http://sixservix.com/blog/david/files/2010/05/webProjectWizard.jpg"><img class="size-medium wp-image-3074  " style="border: 0px initial initial" src="http://sixservix.com/blog/david/files/2010/05/webProjectWizard-300x202.jpg" alt="Interfaz de creación de proyecto" width="300" height="202" /></a><p class="wp-caption-text">Interfaz de creación de proyecto (pulsa sobre la imagen para verla grandota)</p></div>
<p style="text-align: justify">La siguiente interfaz sirve para especificar el servidor con el que trabajará el proyecto, la versión de java utilizada y el contexto web que lo lanzará. Si sois unos vagos -como yo- <span style="text-decoration: underline">habréis utilizado el </span><strong><span style="text-decoration: underline">Glassfish v3</span></strong><span style="text-decoration: underline"> que instala NetBeans</span> para configurarlo como explique en el anterior artículo. Si, por el contrario, os dado por innovar, coleccionais todas las versiones del servidor o, en definitiva, os gusta hacer las cosas bien, puede que tengáis que añadir otro contexto de servidor mediante el botón &#8220;Add&#8221;. Aquí tenéis mi configuración:</p>
<div id="attachment_3075" class="wp-caption aligncenter" style="width: 310px"><a href="http://sixservix.com/blog/david/files/2010/05/webProjectWizard2.jpg"><img class="size-medium wp-image-3075 " src="http://sixservix.com/blog/david/files/2010/05/webProjectWizard2-300x190.jpg" alt="Configurando sel servidor, versión de java y contexto" width="300" height="190" /></a><p class="wp-caption-text">Configurando sel servidor, versión de java y contexto</p></div>
<p style="text-align: justify">La siguiente y última interfaz nos interrogará para saber si queremos incluir algún <em>framework </em>de trabajo como, por ejemplo, <strong>JSF</strong> en nuestro proyecto. Le diremos que &#8220;<em>de momento, no gracias</em>&#8220;. Bastante tenemos con nuestras transacciones (vamos por dos artículos&#8230; y lo que nos queda).</p>
<p style="text-align: justify">Una vez apretemos el botón de &#8216;<em>Finish</em>&#8216; habremos creado un esqueleto de proyecto donde se incluyen las librerías del <strong>JDK 1.6</strong>, de <strong>Glassfih v3</strong> y, para pruebas, <strong>JUnit </strong>y el <strong>contexto embebido</strong> de Glassfsh.</p>
<h3>4. CREANDO UNA UNIDAD DE PERSISTENCIA</h3>
<p style="text-align: justify">Creado el proyecto, aparecerá en el explorador de la izquierda del interfaz un icono muy <em>pituco </em>que representa una bola del mundo (o algo así). Si <strong>pulsáis sobre el mismo con el botón derecho del ratón</strong> y seguís la siguiente ruta de menú <em>New &gt;&gt; Persistence Unit</em>, accederéis a un nuevo mundo de poder y sabiduría&#8230; y al <em>wizard </em>de creación de unidades de persistencia.</p>
<div id="attachment_3077" class="wp-caption aligncenter" style="width: 310px"><a href="http://sixservix.com/blog/david/files/2010/05/PUWizardb.jpg"><img class="size-medium wp-image-3077 " src="http://sixservix.com/blog/david/files/2010/05/PUWizardb-300x167.jpg" alt="El wizard de creación de Unidades de Persistencia" width="300" height="167" /></a><p class="wp-caption-text">El wizard de creación de Unidades de Persistencia</p></div>
<p style="text-align: justify">Aquí tenemos que pararnos durante un rato y explicar que es cada cosa y porque se elige una opción u otra. Al menos, si queremos enterarnos minimamente de que es cada cosa en vez de seguir el tutorial cual robots.</p>
<p style="text-align: justify"><strong>¿Sabemos lo que es una Unidad de Persistencia?</strong> Si, la respuesta es &#8220;si&#8221;, podéis pasar al siguiente párrafo. En caso contrario, os diré que el concepto de unidad de persistencia o <em>persistence unit</em> fue introducido por <strong>JPA1</strong> y <strong>sirve para definir el conjunto de clases de entidad -que representan entidades de una base de datos- que serán gestionadas por nuestro contexto de persistencia</strong> o, lo que es lo mismo, los <em>polvos mágicos</em> que conseguirán que, al crear un objeto de tipo <em>com.six.Boniato</em> y persistirlo, se cree un nuevo registro en la tabla Boniato de nuestra Base de Datos. Además, <strong>contiene un  conjunto de metadatos que configuran el trabajo con dichos datos</strong>. Esos metadatos pueden incluir desde el nivel de traza con el que deseamos tracear el trabajo del motor de persistencia hasta los datos necesarios para crear una conexión directa a la base de datos y hacer que nuestra aplicación no dependa del registro de un <em>datasource </em>en el servidor de aplicaciones.</p>
<p style="text-align: justify">Las <strong>unidades de persistencia</strong> y sus atributos se definen en el fichero <em>persistence.xml</em>. Puede que hayais oído que este fichero se coloca en el directorio <em>/META-INF</em> de nuestra aplicación. Bueno, pues si pero no. No está de más leernos <a href="http://java.sun.com/javaee/6/docs/tutorial/doc/bnbqw.html#bnbrk" target="_blank">lo que nos dice la propia SUN</a> sobre el tema. Son cuatro reglas, pero nos puede evitar numerosas y crípticas <em>com.boni.CascotazoException</em> con trazas similares al comportamiento de Matrix.</p>
<p style="text-align: justify">Lo primero que pide el <em>wizard </em>es un <strong>nombre con el que identificar a nuestra unidad de persistencia</strong>. Si sólo tenemos configurada una única unidad de persistencia, se seleccionará la misma como unidad por defecto. Si tenemos más de una -por ejemplo, una para desarrollo y otro para pruebas en un entorno de integración- podremos utilizar una u otra identificándolas a partir de su nombre.</p>
<p style="text-align: justify">Lo siguiente que pide el <em>wizard </em>es el <strong>proveedor de persistencia</strong> o <em>Persistence Provider</em>. Básicamente, <span style="text-decoration: underline">la implementación de la API de JPA que deseamos utilizar</span>. <strong>NetBeans </strong>incluye varias implementaciones pero, si queréis utilizar <strong>JPA2</strong>, <span style="text-decoration: underline">la única opción</span><strong><span style="text-decoration: underline"> </span></strong><span style="text-decoration: underline">que podéis elegir es <strong>EclipseLink</strong></span>.</p>
<p style="text-align: justify">El tercer dato que pide el <em>wizard </em>es la<strong> fuente de datos</strong> o <em>Data Source</em> con el que va a trabajar la Unidad de Persistencia. Podéis dejar vacío este campo y crear la unidad de persistencia sin <em>Data Source</em> asociado pero <span style="text-decoration: underline">yo</span><span style="text-decoration: underline"> no os lo recomiendo</span>. Eso obligaría a registrar en el fichero <em>persistence.xml</em> todas las propiedades -<strong>especificas para cada proveedor de persistencia</strong>- necesarias para crear localmente el <em>Data Source</em> y, lo que es peor, el tipo de transacciones siempre debería ser <em>RESOURCE_LOCAL</em>, no <em>JTA.</em> ¿Es eso malo? No tiene porque serlo, pero ¿por que restringir vuestra libertad de opción?.</p>
<p style="text-align: justify">Si aún así, queréis hacerlo, <a href="http://www.kauriproject.org/docs/183-kauri/308-kauri/194-kauri.html" target="_blank">aquí</a> tenéis dos buenos ejemplos de como hacerlo.</p>
<p style="text-align: justify">En el caso de que me hagáis caso y decidáis utilizar un <em>Data Source</em>, recordad que vais a desarrollar una aplicación para desplegar en el <strong>Glassfish v3</strong> que configurasteis en el <a href="http://sixservix.com/blog/david/2010/05/10/transacciones-bloqueos-glassfish-v3-ejb31-jpa2/" target="_blank">artículo anterior</a>. El <em>Data Source</em> de <strong>JPA </strong>se corresponde con el <strong>Recurso JDBC</strong> de Glassfish. Yo configuré mi recurso con el nombre global JNDI <em><strong>jdbc/states</strong></em>, así que este es el nombre con el que voy a registrar mi <em>Data Source</em> en mi unidad de persistencia. <span style="text-decoration: underline">Cuando despliegue la aplicación en Glassfish, el acceso a datos estará configurado automáticamente</span>.</p>
<p style="text-align: justify">También <span style="text-decoration: underline">podéis recrear el </span><em><span style="text-decoration: underline">Data Source</span></em><span style="text-decoration: underline"> en </span><strong><span style="text-decoration: underline">NetBeans</span> </strong>¿Para qué? Para poder crear clases de entidad a partir de tablas, mediante <em>wizards </em>del IDE; validar que vuestro modelo se ajuste a vuestras clases, etc. Tener el <em>Data Source</em> de vuestro servidor de aplicaciones configurado en el IDE es <em>guayabero, guayabero</em> y, encima, bastante sencillo de implementar hasta bajo nivel, la conexión física. Os dejo una ruta gráfica:</p>
<div id="attachment_3078" class="wp-caption aligncenter" style="width: 310px"><a href="http://sixservix.com/blog/david/files/2010/05/PUWizardc.jpg"><img class="size-medium wp-image-3078" src="http://sixservix.com/blog/david/files/2010/05/PUWizardc-300x240.jpg" alt="PUWizardc" width="300" height="240" /></a><p class="wp-caption-text">Como configurar un Data Source en NetBeans</p></div>
<p style="text-align: justify">Una vez creado (o no) el <em>Data Source</em> de la <strong>Unidad de Persistencia</strong>, encontramos en el <em>wizard </em>un <em>checkbox </em>que <strong>permite indicar si se desea trabajar con o sin JTA</strong>, o lo que es lo mismo, si queremos que el contenedor gestione las transacciones por nosotros o queremos meter mano y configurarlas<em> a pelo Capello</em>. La elección es vuestra pero, personalmente, me fio bastante mas del contenedor que de mi mismo. De hecho, me fio bastante mas de que el <a href="http://www.clubatleticodemadrid.com/" target="_blank">Atleti</a> gane 10 años seguidos la Champions League de que yo no me deje alguna transaccion abierta donde no deba.</p>
<p style="text-align: justify">La gestión local de transacciones sólo se recomienda en casos muy específicos, donde se desea tener control de transaccionalidad intra-método de EJB.</p>
<p style="text-align: justify">Dependiendo de vuestra elección, se creará un <tt>jta-data-source, </tt>para trabajar con <em>Data Sources</em> gestionados con <strong>JTA</strong>, o un  <tt>non-jta-data-source, </tt>para los<em> Data Sources</em> que no trabajen con <strong>JTA</strong>.</p>
<p style="text-align: justify">La última opción que presenta el <em>wizard </em>es la <strong>estrategia de creación de tablas</strong>. Dependiendo de la estrategia seleccionada, el IDE intentará o no crear las tablas en vuestra base de datos si no las encuentra.</p>
<p style="text-align: justify">Finalmente, la configuración de mi <em>wizard </em>queda tal que así:</p>
<div id="attachment_3079" class="wp-caption aligncenter" style="width: 310px"><a href="http://sixservix.com/blog/david/files/2010/05/webProjectWizard4.jpg"><img class="size-medium wp-image-3079 " src="http://sixservix.com/blog/david/files/2010/05/webProjectWizard4-300x167.jpg" alt="El New Persistence Unit wizard" width="300" height="167" /></a><p class="wp-caption-text">El New Persistence Unit wizard</p></div>
<p style="text-align: justify">Una vez creada la <strong>Unidad de Persistencia</strong>, estamos preparados para crear código con <strong>JPA2</strong>, <strong>JTA</strong>, transacciones, bloqueos y hasta tirabuzones triples&#8230; pero eso lo veremos en la siguiente entrega.</p>
<p style="text-align: justify">De nuevo, nos hemos ido hasta cerca de las <strong>1500 palabras</strong>, sobrepasando con mucho el máximo deseable para un artículo en un <em>blog</em>. Así pues, os emplazo a una <strong>tercera </strong>y espero que definitiva entrega&#8230; si aún os siguen quedando ganas de trabajar con <strong>EJB3.1</strong> y <strong>JPA2</strong> :)</p>
<p style="text-align: justify"><strong><span style="color: #008000">DISCLAIMER</span></strong></p>
<p style="text-align: justify">No tengo mucho <em>feedback </em>sobre esta serie de artículos, exceptuando las del ya mítico Dr. Arranz y mis secuaces tuiteros. Una sensación de tostón técnico invade todo mi ser, así que, si tienes algún consejo o sugerencia para mejorar la tercera entrega, no dudes en hacérmelo saber.</p>


<p>Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/08/24/logging-glassfish/' rel='bookmark' title='Permanent Link: Arquitectura de logging en Glassfish'>Arquitectura de logging en Glassfish</a> <small>Aprende como funciona el sistema de registro o logging en...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/06/02/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-iii/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (III)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (III)</a> <small>Tercera parte del tutorial sobre como utilizar transacciones y bloqueos...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/05/10/transacciones-bloqueos-glassfish-v3-ejb31-jpa2/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (I)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (I)</a> <small>Un sencillo tutorial sobre como utilizar transacciones y bloqueos con...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/05/12/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-ii/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (I)</title>
		<link>http://sixservix.com/blog/david/2010/05/10/transacciones-bloqueos-glassfish-v3-ejb31-jpa2/</link>
		<comments>http://sixservix.com/blog/david/2010/05/10/transacciones-bloqueos-glassfish-v3-ejb31-jpa2/#comments</comments>
		<pubDate>Mon, 10 May 2010 04:50:19 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[EclipseLink]]></category>
		<category><![CDATA[ejb]]></category>
		<category><![CDATA[ejb3.1]]></category>
		<category><![CDATA[glassfish]]></category>
		<category><![CDATA[glassfish v3]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[JPA2]]></category>
		<category><![CDATA[netbeans]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=2866</guid>
		<description><![CDATA[Un sencillo tutorial sobre como utilizar transacciones y bloqueos con JPA2 en Glassfish v3 con JPA2. Aunque no lo parezca, esta ensalada de siglas tiene sentido...


Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/08/24/logging-glassfish/' rel='bookmark' title='Permanent Link: Arquitectura de logging en Glassfish'>Arquitectura de logging en Glassfish</a> <small>Aprende como funciona el sistema de registro o logging en...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/06/02/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-iii/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (III)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (III)</a> <small>Tercera parte del tutorial sobre como utilizar transacciones y bloqueos...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/05/12/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-ii/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (II)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (II)</a> <small>Segunda parte del tutorial sobre como utilizar transacciones y bloqueos...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom: 0cm;text-align: justify"><img class="alignleft size-full wp-image-2870" style="border: 0pt none;margin-right: 10px" src="http://sixservix.com/blog/david/files/2010/04/persistencia.jpg" alt="persistencia" width="300" height="220" /><span style="color: #000000">Tal y como votaron los lectores del <em>blog </em>hace un par de semanas, os presento un minitutorial + prototipo en <strong>varias entregas</strong>, sobre cómo implementar transacciones y bloqueos utilizando <strong>EJB3.1</strong> y <strong>JPA2</strong> en <strong>Glassfish</strong>.</span></p>
<p style="margin-bottom: 0cm;text-align: justify"><span style="color: #000000">No me gusta tener que partir los artículos pero, la verdad es que está quedando francamente largo y corría el riesgo de convertirse en un <strong>ladrillo infumable</strong>.</span></p>
<p style="margin-bottom: 0cm;text-align: justify"><span style="color: #000000"> </span><span style="color: #000000">La teoría dice que el código proporcionado en este tutorial debería funcionar en cualquier servidor de aplicaciones compatible con <a href="http://www.theserverside.com/news/1363662/Java-EE-6-Overview" target="_blank">Java EE6</a> y con cualquier implementación de <a href="http://stackoverflow.com/questions/1341665/differences-between-jpa-and-jpa2" target="_blank">JPA2</a>, pero la teoría también decía que en Irak había armas de destrucción masiva&#8230; y aún las están buscando.</span></p>
<p style="margin-bottom: 0cm;text-align: justify"><span style="color: #000000"><a href="https://glassfish.dev.java.net/public/comparing_v2_and_v3.html" target="_blank">Glassfish v3</a> y <a href="http://blogultura.com/java/netbeans-6-8-liberado/" target="_blank">Netbeans 6.8</a> -el <strong>IDE </strong>mejor integrado con este servidor de aplicaciones- tienen soporte nativo de <a href="http://en.wikipedia.org/wiki/EclipseLink" target="_blank">EclipseLink</a>, la implementación de referencia de <strong>JPA2</strong> y vástago hipermineralizado y supervitaminado de <strong>Oracle Toplink</strong>.</span></p>
<p style="margin-bottom: 0cm;text-align: justify"><span style="color: #000000">Hay otras implementaciones de <strong>JPA2</strong>, como la de <strong>Hibernate 3.5</strong> -lanzada el 31 de marzo de este año- o la de <strong>openJPA 2</strong> -lanzada el 22 de abril-, pero como habéis podido comprobar son versiones muy recientes, no maduras y que pueden funcionar como los pimientos de Padrón: <span style="text-decoration: underline">a veces si y a veces <em>non</em></span>.</span></p>
<h3 style="margin-bottom: 0cm;text-align: justify"><span style="color: #888888">1. CREANDO NUESTRA BASE DE DATOS DE PRUEBAS</span></h3>
<p style="margin-bottom: 0cm;text-align: justify"><span style="color: #000000">Lo primero que debemos hacer es montar una pequeña base de datos con la que trabajará nuestro prototipo. Vamos a crear una típica <strong>estructura cabecera-lineas</strong>, donde un cliente puede tener de 0 a <em>n</em> pedidos asociados, teniendo en cuenta que un pedido puede crearse sin asociar a ningún cliente:</span></p>
<p style="margin-bottom: 0cm;text-align: justify"><img class="aligncenter size-full wp-image-2887" src="http://sixservix.com/blog/david/files/2010/04/diagramaJPA.jpg" alt="diagramaJPA" width="127" height="208" /></p>
<p style="margin-bottom: 0cm;text-align: justify"><span style="color: #000000">¿Que porqué le he puesto esos <em>nombroncios </em>a las tablas? Pues porque así los debí encontrar en alguno de las decenas de ejemplos que he visto para destilar este tutorial y así se quedaron.</span></p>
<p style="margin-bottom: 0cm;text-align: justify"><span style="color: #000000">En cualquier caso, en <a href="http://dl.dropbox.com/u/3320460/crea_tablas.sql" target="_blank"><strong>este enlace</strong></a> tenéis el <strong><em>script </em>SQL </strong>necesario para crear las tablas, tal y como yo las he creado. He generado el <em>script </em>haciendo ingeniera inversa con nuestra base de datos -una vez más, vaguería pura- pero <span style="text-decoration: underline">debe funcionar <em>as-is</em>, o con pequeños cambios, en cualquier base de datos</span>.</span></p>
<h3 style="margin-bottom: 0cm;text-align: justify"><span style="color: #888888">2. INSTALANDO Y CONFIGURANDO GLASSFISH</span></h3>
<p style="margin-bottom: 0cm;text-align: justify"><span style="color: #000000">No voy a perder ni un instante en explicaros como instalar <strong>Glassfish</strong>. Primero, porque es más sencillo que el asa de un cubo y, segundo; porque si yo he sido capaz de leer y comprender este <a href="http://dl.dropbox.com/u/3320460/glassfish_v3_installation.pdf" target="_blank"><strong>pequeño ladrillete</strong></a> de 32 páginas, cualquiera podéis hacerlo.</span></p>
<p style="margin-bottom: 0cm;text-align: justify"><span style="color: #000000">Una vez instalado el <strong>Glassfish v3</strong> y creada nuestra base de datos, tenemos que configurar un <em>Data Source </em>o fuente de datos que nos permita acceder y modificar la estructura creada en el punto anterior, siguiendo los siguientes pasos:</span></p>
<ul style="text-align: justify">
<li><span style="color: #000000"><strong>Cargar la </strong><strong>librería JDBC de acceso a nuestra base de datos en el <em>classpath</em> de </strong><strong>Glassfish</strong>: Para hacerlo, debemos copiar el <em>jar </em>de la librería en la siguiente ruta <em>/</em>instalación de glassfish<em>/domains/</em>dominio que vayamos a utilizar (normalmente, domain1)<em>/lib</em>. En mi caso en concreto, con <strong>Glassfish </strong>instalado en Windows, la ruta es </span>&#8220;<em>c:\Archivos de programa\sges-v3\glassfish\domains\domain1\lib\&#8221; </em>y ahi he copiado la librería JDBC especifica para bases de datos Oracle:  <em>ojdbc14_g.jar</em>.</li>
<li><strong>Crear un nuevo conjunto de conexiones o <em>Connection Pool </em>en el servidor: </strong>a través de la dirección <span style="color: #0000ff"><strong>http://localhost:4848</strong></span> podréis acceder a la consola de administración de <strong>Glassfish</strong>. Si navegáis por el árbol de opciones hasta <em>Recursos &gt;&gt; JDBC &gt;&gt; Conjunto de Conexiones</em>, veréis algunos creados por defecto en el servidor y podréis crear uno mediante el botón &#8216;Nuevo&#8217;. Al crear un nuevo conjunto de conexiones, nos preguntará por la Base de Datos con la que vamos a trabajar, básicamente, para que no tengamos que configurar a manubrio la clase de implementación de la interfaz <em>java.sql.Driver</em>. También nos pedirá que indiquemos el <a href="http://db.apache.org/derby/docs/10.3/ref/rrefjta18596.html" target="_blank">tipo de recurso JDBC</a> que deseamos crear. En el segundo paso de la creación, se indica la configuración propiamente dicha, desde el número de conexiones a el <em>host</em>, usuario y <em>password </em>de la base de datos en si. Pero <span style="text-decoration: underline">lo realmente importante, es la configuración de la transaccionalidad del <em>DataSource</em></span>. Para no eternizarnos explicando parámetro a parámetro lo que hay que poner, os pongo una copia de mi <em>DataSource</em>, configurada para una base de datos Oracle, que está en un <em>host </em>denominado NEDWARD (por NED FLANDERS)</li>
</ul>
<div id="attachment_3034" class="wp-caption aligncenter" style="width: 282px"><a href="http://sixservix.com/blog/david/files/2010/05/JDBC_1b.JPG"><img class="size-medium wp-image-3034" src="http://sixservix.com/blog/david/files/2010/05/JDBC_1b-272x300.jpg" alt="Pulsa sobre la imagen para verla grandota" width="272" height="300" /></a><p class="wp-caption-text">Pulsa sobre la imagen para verla grandota</p></div>
<div id="attachment_3036" class="wp-caption aligncenter" style="width: 282px"><a href="http://sixservix.com/blog/david/files/2010/05/JDBC_2.jpg"><img class="size-medium wp-image-3036" src="http://sixservix.com/blog/david/files/2010/05/JDBC_2-272x300.jpg" alt="Pulsa en la imagen para que se vea grandota" width="272" height="300" /></a><p class="wp-caption-text">Pulsa en la imagen para que se vea grandota</p></div>
<ul style="text-align: justify">
<li>Por último, tendréis que <strong>crear un Recurso JDBC</strong> que no es, ni mas ni menos, que un envoltorio que pondrá Glassfish sobre vuestro conjunto de conexiones y al que daréis un nombre JNDI con el que lo identificareis en vuestras aplicaciones. Os muestro, de nuevo, mi interfaz de configuración, donde <strong>he creado un Recurso JDBC con el nombre JNDI </strong><em><strong>jdbc/states</strong></em>.</li>
</ul>
<div id="attachment_3042" class="wp-caption aligncenter" style="width: 310px"><a href="http://sixservix.com/blog/david/files/2010/05/JDBC_3.jpg"><img class="size-medium wp-image-3042" src="http://sixservix.com/blog/david/files/2010/05/JDBC_3-300x280.jpg" alt="Pulsa en la imagen para que se vea grande como Australia" width="300" height="280" /></a><p class="wp-caption-text">Pulsa en la imagen para que se vea grande como Australia</p></div>
<p style="text-align: justify">
<p style="text-align: justify">Con esto <span style="text-decoration: underline">hemos acabado toda la configuración de </span><strong><span style="text-decoration: underline">Glassfish </span></strong><span style="text-decoration: underline">que necesitamos para ejecutar este ejemplo.</span> A partir de ahora, es cuando <strong>viene el caviar</strong>&#8230; :)</p>
<p style="text-align: justify"><span style="text-decoration: underline">Permaneced atentos a la </span><strong><span style="text-decoration: underline">segunda parte del artículo</span></strong>.</p>


<p>Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/08/24/logging-glassfish/' rel='bookmark' title='Permanent Link: Arquitectura de logging en Glassfish'>Arquitectura de logging en Glassfish</a> <small>Aprende como funciona el sistema de registro o logging en...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/06/02/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-iii/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (III)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (III)</a> <small>Tercera parte del tutorial sobre como utilizar transacciones y bloqueos...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/05/12/transacciones-y-bloqueos-en-glassfish-v3-con-ejb3-1-y-jpa2-ii/' rel='bookmark' title='Permanent Link: Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (II)'>Transacciones y bloqueos en Glassfish v3 con EJB3.1 y JPA2 (II)</a> <small>Segunda parte del tutorial sobre como utilizar transacciones y bloqueos...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/05/10/transacciones-bloqueos-glassfish-v3-ejb31-jpa2/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>James Gosling deja Oracle</title>
		<link>http://sixservix.com/blog/david/2010/04/12/james-gosling-deja-oracle/</link>
		<comments>http://sixservix.com/blog/david/2010/04/12/james-gosling-deja-oracle/#comments</comments>
		<pubDate>Mon, 12 Apr 2010 04:50:43 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[tecnologías de la información]]></category>
		<category><![CDATA[james gosling]]></category>
		<category><![CDATA[jhonathan schwartz]]></category>
		<category><![CDATA[kohsuke kawaguchi]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[simon phipps]]></category>
		<category><![CDATA[sun]]></category>
		<category><![CDATA[Tim Bray]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=2708</guid>
		<description><![CDATA[James Gosling, 'padre' del lenguaje de programación java ha dejado Oracle ¿Cómo afectará esto a la compañía y a la comunidad de desarrollo?


Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/06/17/oracle_y_bloggers/' rel='bookmark' title='Permanent Link: Compartiendo mesa y mantel con Oracle'>Compartiendo mesa y mantel con Oracle</a> <small>Ayer acudí a un encuentro de bloggers organizado por Oracle...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-full wp-image-2710" style="border: 0pt none;margin-right: 10px;margin-bottom: 3px" src="http://sixservix.com/blog/david/files/2010/04/James_Gosling.jpg" alt="James_Gosling" width="200" height="275" /><strong>James Gosling</strong>, el <em>padre</em> del lenguaje de programación <strong>java</strong>, deja <strong>Oracle</strong>. El día 9 de abril, mediante <a href="http://nighthacks.com/roller/jag/entry/time_to_move_on" target="_blank">una entrada en su <em>blog</em></a>, confirmaba los rumores anunciando que había abandonado la compañía una semana antes.</p>
<p style="text-align: justify"><strong>Gosling </strong>se une a una larga y creciente lista de notables ex-empleados de <strong>SUN</strong>, que han renunciado a su puesto desde que <strong>Oracle </strong>la comprara en enero y que incluye a personalidades como el CEO <a href="http://en.wikipedia.org/wiki/Jonathan_I._Schwartz" target="_blank">Jhonathan Schwartz</a>; el co-inventor del lenguaje XML, <a href="http://en.wikipedia.org/wiki/Tim_Bray" target="_blank">Tim Bray;</a> el creador de Hudson, <a href="http://weblogs.java.net/blog/kohsuke/archive/2010/04/05/good-bye-sunoracle" target="_blank">Kohsuke Kawaguchi</a>; o el responsable de <em>open source</em>, <a href="http://www.fayerwayer.com/2010/03/chief-open-source-officer-de-sun-deja-la-compania/" target="_blank">Simon Phipps</a>.</p>
<p style="text-align: justify">La marcha de <strong>Gosling </strong>y sus compañeros supone un duro golpe para la comunidad de desarrollo que ha crecido alrededor del lenguaje <strong>java,</strong> aunque técnicos como <a href="http://twitter.com/jerolba" target="_blank">Jerónimo López</a> crean que &#8220;<em>para el sector, todo esto que está pasando es  positivo. El panorama se llenará de nuevas empresas repletas de gente con muchas  ideas, que podrán desarrollar/explorar con aún más libertad que cuando  estaban en <strong>SUN</strong>. Seguro que muchas de esas ideas impulsarán/crearán áreas  nuevas</em>&#8220;.</p>
<p style="text-align: justify">Además, aunque algunos crean que los resultados de <strong>Oracle </strong>y sus ventas no se verán  afectadas por la marcha de <strong>Gosling, </strong>como <a href="http://weblogs.javahispano.org/jh/entry/nos_presentamos_iii" target="_blank">Abraham Otero</a> que comenta en <a href="http://javahispano.org/contenidos/es/y_despues_de_kohsuke__llega_el_turno_de___/?menuId=ANNOUNCEMENTS" target="_blank">javaHispano</a> &#8220;<em>&#8230; las &#8216;empresas serias&#8217; ni sabían quién era el &#8216;hippie&#8217; ese  de <strong>Gosling</strong>&#8230;</em>&#8220;, la pregunta que debemos hacernos todos y, especialmente, los accionistas de <strong>Oracle </strong>es: <strong>¿vale más o menos Oracle sin todos estos técnicos dentro de ella?</strong> Si la valoración de una empresa se basa no sólo en sus activos financieros sino en su posibilidad de generar beneficios en un futuro, ¿se verá penalizada la valoración de <strong>Oracle </strong>en bolsa? ¿Se reducirá su capacidad de desarrollar nuevos productos y tecnologías?</p>
<p style="text-align: justify">Aunque no suelo ser un buen oráculo, pronostiqué deserciones masivas de técnicos en <a href="http://sixservix.com/blog/david/2010/02/01/el-traje-nuevo-del-emperador/" target="_blank">antiguos artículos</a> y en el <a href="http://www.javahispano.org/contenidos/es/javahispano_podcast__074__impresiones_del_webcast_de_larry_ellison/" target="_blank"><em>podcast </em>de javaHispano</a> donde comentamos la compra de <strong>SUN </strong>por parte de <strong>Oracle. SUN </strong>ya no es la compañía que atraía y contrataba a los mejores técnicos.</p>
<p style="text-align: justify">¿A dónde llevará todo esto? Nadie puede pronosticarlo, pero sí podemos asegurar que el panorama de java y su ecosistema va a cambiar radicalmente.</p>


<p>Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/06/17/oracle_y_bloggers/' rel='bookmark' title='Permanent Link: Compartiendo mesa y mantel con Oracle'>Compartiendo mesa y mantel con Oracle</a> <small>Ayer acudí a un encuentro de bloggers organizado por Oracle...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/04/12/james-gosling-deja-oracle/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Trabajando con Twitter y Java</title>
		<link>http://sixservix.com/blog/david/2009/12/15/twitter-y-java/</link>
		<comments>http://sixservix.com/blog/david/2009/12/15/twitter-y-java/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 06:45:22 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[tuenti]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[twitter4j]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=1308</guid>
		<description><![CDATA[Si no tienes ni idea de lo que es Twitter estás out, fuera, finito, acabado&#8230; y te estás perdiendo el big kahuna del momento en Internet. Te recomiendo que te pongas las pilas y que lo hagas YA.
Si eres un desarrollador y piensas &#8220;A mí plin Paquirrín. Eso no tiene nada que ver conmigo&#8220;, disculpa [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-full wp-image-1310" style="margin-left: 8px;margin-right: 8px" src="http://sixservix.com/blog/david/files/2009/12/twitter-social-icons.jpg" alt="twitter-social-icons" width="192" height="190" />Si no tienes ni idea de lo que es <strong>Twitter</strong> estás <em>out</em>, fuera, <em>finito</em>, acabado&#8230; y te estás perdiendo el <em>big kahuna</em> del momento en Internet. Te recomiendo que te pongas las pilas y que lo hagas YA.</p>
<p style="text-align: justify">Si eres un desarrollador y piensas &#8220;<em>A mí plin Paquirrín. Eso no tiene nada que ver conmigo</em>&#8220;, disculpa si te lo digo con crudeza: <span style="text-decoration: underline">eres un <em>looser</em></span>. Saca durante un instante la cabeza de <strong>Hibernate </strong>y <strong>Spring </strong>porque te están impidiendo ver el sol :).</p>
<p style="text-align: justify"><strong>Twitter </strong>no es sólo una <em>página güel</em>, no es sólo un &#8220;<em>Facebook pero en pequeño</em>&#8221; ni la última tontuna de los modernos de turno. <strong>Twitter es una plataforma</strong> y, como tal, debes aprender a desarrollar para ella. Porque nunca sabes cuándo te puede venir bien utilizarla y porque, créeme, a tus clientes les puede parecer más o menos interesante que utilices Toplink, Hibernate o SQL con escoplo y martillo, pero es probable que alguno te pida algo para <strong>Twitter</strong>. ¿Quieres quedar como un zocolotroco desfasado o como un <em>gurú del Interné</em>? Invertir <strong>5 minutos</strong> en la lectura de este articulo separa una cosa de la otra.<span id="more-1308"></span></p>
<h3 style="text-align: justify">¿UNA PLATAFORMA?</h3>
<p style="text-align: justify">Si amigo, <strong>Twitter  es una plataforma</strong>. Y ¿por qué es una plataforma? Porque <span style="text-decoration: underline">te proporciona una completa <strong>API REST </strong>para que utilices todos los servicios que ofrece desde tu propia aplicación</span> de una forma sencilla y gratuita.</p>
<p style="text-align: justify">Ésta es la clave del éxito de páginas como Twitter o Facebook, su espíritu de <strong>auténticas plataformas donde terceros desarrollen sus propias aplicaciones</strong>.</p>
<div id="attachment_1328" class="wp-caption alignright" style="width: 218px"><a href="http://sixservix.com/blog/david/files/2009/12/plataforma.jpg"><img class="size-full wp-image-1328" src="http://sixservix.com/blog/david/files/2009/12/plataforma.jpg" alt="plataforma" width="208" height="208" /></a><p class="wp-caption-text">Sí, twitter es una plataforma, pero NO de este tipo...</p></div>
<p style="text-align: justify">Sí, Facebook está muy bien, pero ¿alguien puede imaginárselo sin los cientos de juegos del tipo &#8220;¿Quien es el más listo de tus amigos?&#8221; o &#8220;El Granjero que llevas dentro&#8221;? ¿Y sin las miles de aplicaciones para enviar osos amorosos o bocatas de calamares a tus amigos? <span style="text-decoration: underline">La genialidad de Twitter y Facebook es conseguir que terceros desarro</span><span style="text-decoration: underline">l</span><span style="text-decoration: underline">len, sin coste alguno para ellos, y hagan crecer y enriquezcan la plataforma</span>. ¿Que esos terceros también se lucran? &#8220;Genial&#8221;, piensan ellos, así ganamos todos.</p>
<p style="text-align: justify">Por poneros un ejemplo de lo que NO es una plataforma, tenemos a nuestro propio clon local y <em>reggaetonero </em>de Facebook: <em>el Tuenti</em>. No hay un enlace a &#8220;Desarrolladores&#8221; o a &#8220;API&#8221; en la web de Tuenti. Ellos se lo guisan y ellos se lo comen. Vale, veremos como les va, pero, de momento, <a href="http://trends.google.com/websites?q=tuenti.com%2C+facebook.com&amp;geo=ES&amp;date=all&amp;sort=1" target="_blank">van cuesta abajo y sin frenos</a>.</p>
<h3 style="text-align: justify">VALE ¿CÓMO EMPEZAMOS?</h3>
<p style="text-align: justify">Lo primero que tienes que hacer es dar de alta una cuenta en <strong>Twitter</strong>.<strong> </strong>¿Por qué? Porque con esa cuenta podrás registrar tus aplicaciones. Necesitamos registrar las aplicaciones en Twitter para utilizar <a href="http://oauth.net/" target="_blank">OAuth</a> como medio de autenticación.</p>
<p style="text-align: justify">La verdad, podríamos pasar del <strong>OAuth</strong> para hacer nuestra primera aplicación, pero ya que nos ponemos a juguetear con Twitter, mejor aún si aprendemos algo nuevo y ¡Carambolas! <strong>¡El OAUth mola!</strong> :)</p>
<p style="text-align: justify">
<div id="attachment_1336" class="wp-caption alignleft" style="width: 236px"><img class="size-full wp-image-1336 " src="http://sixservix.com/blog/david/files/2009/12/oauth.jpg" alt="Key y Secret de Oauth que se obtiene al registrar la aplicación" width="226" height="262" /><p class="wp-caption-text">Key y Secret de Oauth que se obtiene al registrar la aplicación</p></div>
<p style="text-align: justify">Hablar de <strong>OAuth </strong>no es el objetivo de este post, pero lo describiré de un modo breve. Básicamente, el método de autenticación OAuth se basa en que, <strong>el usuario no se autentica en tu web mediante usuario y contraseña</strong> sino que lo hace en la plataforma que gestione la autenticación (por ejemplo, Twitter) y ésta te da un <em>token</em> de autenticación que es el que tu guardas y utilizas para comunicarte en el futuro con dicha plataforma.</p>
<p style="text-align: justify">Evidentemente, ese <em>token </em>vale para y SÓLO para tu aplicación. Ahí está el truco. Y, para que la plataforma sepa qué aplicación es la que está requiriendo autenticación, te proporciona unas claves que tú envías cuando haces las llamadas de validación de claves. Twitter, al <a href="http://twitter.com/oauth_clients/new" target="_blank">registrar una aplicación</a>, te da las claves necesarias para  trabajar con <strong>OAuth</strong> desde tu aplicación.</p>
<p style="text-align: justify">
<p style="text-align: justify">
<p style="text-align: justify">Ah, una última cosa: como desarrolladores, Twitter nos asigna una serie de cuotas para el uso de sus servicios (recordemos, gratuitos). En concreto, <strong>150 llamadas a la API por hora y por IP/Cuenta de Usuario</strong>.</p>
<p style="text-align: justify">Si nos hemos emocionado con todo esto de las plataformas y tenemos pensado desarrollar <em>La Madre de todas las Aplicaciones de Twitter</em>, podemos solicitar en <a href="http://twitter.com/help/request_whitelisting" target="_blank">este enlace</a> que nos amplíen la cuota <strong>hasta 10.000 llamadas a la hora</strong>, pero, de momento, no creo que sea necesario.</p>
<p style="text-align: justify">Ahora sí, tenemos todo lo que hay que tener para empezar a desarrollar nuestra primera aplicación para <strong>Twitter</strong>.</p>
<h3 style="text-align: justify">MANOS A LA OBRA</h3>
<p style="text-align: justify">Como hemos comentado antes, <span style="text-decoration: underline">la API para trabajar con <strong>Twitter</strong> es una <strong>API REST</strong></span>. Si no sabes lo que es REST, aquí tienes un <a href="http://sixservix.com/blog/david/2009/09/30/explicando-rest-a-mam/" target="_blank">excelente artículo</a> :P sobre el tema, pero, en cualquier caso, no te preocupes. <span style="text-decoration: underline">No te hace falta saber absolutamente nada de REST</span> porque utilizaremos uno de los <strong>envoltorios Java</strong> que ya están creados. Si eres capaz de invocar un <em>System.out.println()</em>, serás capaz de trabajar con esta API.</p>
<p style="text-align: justify">En la propia <a href="http://apiwiki.twitter.com/Libraries" target="_blank">página de librerías Twitter</a> tienes un montón de <em>frameworks </em>ordenados por lenguaje. Voy a centrarme en las opciones que hay para Java, el lenguaje que utilizo y amo, y dentro de éstas, en <a href="http://yusuke.homeip.net/twitter4j/en/index.html" target="_blank">Twitter4j</a>. Más que nada, porque es la que mejor diseño y documentación tiene.</p>
<p style="text-align: justify">Vamos a ir describiendo, paso por paso, <strong>cómo crear nuestra aplicación java/twitter</strong>:</p>
<ol>
<li>Descargamos la librería de la web de Twitter4j. En un fichero <em>zip</em>, encontraremos tanto la librería en sí como el resto de librerías que necesita para funcionar y, si lo preferimos, un fichero <em>pom </em>de <strong>Maven </strong>con todas las dependencias.</li>
<li>Instalamos el conjunto de librerías, tanto Twitter4j como aquellas de las que depende, haciéndolas accesibles a nuestro <em>classpath</em></li>
<li>Nos crearemos la clase<em> BoniTwitterTest</em> donde copiaremos el siguiente código:</li>
<p style="text-align: justify">
<p>[java autolinks="false" classname="BoniTwitterTest" collapse="true" firstline="1" gutter="true" htmlscript="false" light="false" padlinenumbers="false" smarttabs="true" tabsize="4" toolbar="true"]</p>
<p>import twitter4j.Twitter;<br />
import twitter4j.TwitterException;<br />
import twitter4j.Status;<br />
import twitter4j.http.RequestToken;<br />
import twitter4j.http.AccessToken;</p>
<p>import java.io.BufferedReader;<br />
import java.io.InputStreamReader;<br />
import java.util.Hashtable;</p>
<p>public class BoniTwitterTest {</p>
<p> private static Hashtable&lt;String, AccessToken&gt; almacen = new Hashtable&lt;String, AccessToken&gt;();</p>
<p> public static void main(String args[]) throws Exception {</p>
<p> BufferedReader br = new BufferedReader(new InputStreamReader(System.in));<br />
 while (true) {<br />
 Twitter twitter = getTwitter();<br />
 System.out.println(&quot;Introduzca su nombre de usuario:&quot;);<br />
 String usuario = br.readLine();<br />
 AccessToken accessToken = almacen.get(usuario);<br />
 while (accessToken == null) {<br />
 RequestToken requestToken = twitter.getOAuthRequestToken();<br />
 System.out.println(&quot;Visita la siguiente página web y autoriza el acceso a tu cuenta:&quot;);<br />
 System.out.println(requestToken.getAuthorizationURL());<br />
 System.out.print(&quot;Una vez visitada, introduce el PIN y pulsa enter:&quot;);<br />
 String pin = br.readLine();<br />
 try {<br />
 if (pin.length() &gt; 0) {<br />
 accessToken = twitter.getOAuthAccessToken(requestToken, pin);<br />
 } else {<br />
 accessToken = requestToken.getAccessToken();<br />
 }<br />
 // Se guarda el token de autenticación para utilizar en un futuro<br />
 storeAccessToken(usuario, accessToken);<br />
 } catch (TwitterException te) {<br />
 if (401 == te.getStatusCode()) {<br />
 System.out.println(&quot;No ha sido posible obtener el token de autentiación&quot;);<br />
 } else {<br />
 te.printStackTrace();<br />
 }<br />
 twitter = getTwitter();<br />
 }<br />
 } // FIN del bucle WHILE que asegura la autenticación<br />
 twitter.setOAuthAccessToken(accessToken);<br />
 System.out.println(&quot;Introduzca su nuevo estado de Twitter o NADA si desea salir y pulse ENTER:&quot;);<br />
 String status = br.readLine();<br />
 if (status == null || status.length() == 0) {<br />
 System.out.println(&quot;Gracias por usar la aplicación. Adios !!!&quot;);<br />
 System.exit(0);<br />
 } else {<br />
 Status tstatus = twitter.updateStatus(status);<br />
 System.out.println(&quot;Se ha actualizado con exito el estado a [&quot; + tstatus.getText() + &quot;]&quot;);<br />
 }</p>
<p> } // FIN del bucle WHILE principal de la aplicación</p>
<p> }</p>
<p> /**<br />
 * Este metodo nos devolvera una instancia del objeto Twitter con la OAuyth Key y el OAuth Secret configurados<br />
 * @return una instancia del objeto Twitter<br />
 */<br />
 private static Twitter getTwitter() {<br />
 Twitter twitter = new Twitter();<br />
 twitter.setOAuthConsumer(&quot;OAuth Key&quot;, &quot;OAuth Secret&quot;);<br />
 return twitter;<br />
 }</p>
<p> /**<br />
 * Guarda el token de autenticación de un usuario en una Hashtable<br />
 * @param usuario el ID de usuario que servira como clave de guardado<br />
 * @param at el token de autenticación<br />
 */<br />
 private static void storeAccessToken(String usuario, AccessToken at) {<br />
 System.out.println(&quot;USUARIO TWITTER &quot; + usuario);<br />
 System.out.println(&quot;TOKEN &quot; + at.getToken());<br />
 System.out.println(&quot;TOKEN SECRET &quot; + at.getTokenSecret());<br />
 almacen.put(usuario, at);<br />
 }</p>
<p>}[/java]</p>
<p style="text-align: justify">
<li>Tenéis que sustituir las cadenas de texto  &#8216;<em>OAuth Key</em>&#8216; y &#8216;<em>OAuth Secret</em>&#8216; por las claves que os haya proporcionado <strong>Twitter </strong>al registrar vuestra aplicación.</li>
<li>¿Que qué hace este código? Pues, básicamente, comprobar si tenéis el <em>token </em>de validación de un usuario en el sistema y, si no lo tenéis, pediros que visitéis una web para obtener un código o <strong>PIN de autorización</strong> que demuestre que el usuario ha autorizado a tu aplicación a acceder a la API de <strong>Twitter </strong>en su nombre.
<div id="attachment_1379" class="wp-caption aligncenter" style="width: 668px"><img class="size-full wp-image-1379 " src="http://sixservix.com/blog/david/files/2009/12/twitter0.jpg" alt="Esta es la web en la que el usuario autoriza o no a tu aplicación para trabajar en tu nomre en Twitter" width="658" height="313" /><p class="wp-caption-text">Ésta es la web en la que el usuario autoriza o no a tu aplicación para trabajar en tu nombre en Twitter</p></div>
<p><div id="attachment_1380" class="wp-caption aligncenter" style="width: 668px"><img class="size-full wp-image-1379 " src="http://sixservix.com/blog/david/files/2009/12/twitter1.jpg" alt="Este es el PIN que te proporciona Twitter para que introduzcas en tu aplicación" width="658" height="313" /><p class="wp-caption-text">Éste es el PIN que te proporciona Twitter para que introduzcas en tu aplicación</p></div></li>
<li>Una vez que introduces el <strong>PIN</strong>, obtienes el <em>token</em> de autenticación y ya puedes solicitar los servicios de <strong>Twitter </strong>en nombre del usuario autenticado.</li>
<li>Nuestra pequeña aplicación, se limitará a solicitarnos el <em>status </em>con el que queremos actualizar la cuenta de <strong>Twitter </strong>del usuario autenticado.</li>
<li>Si actualizamos el <em>status </em>con la frase &#8216;<em>Actualizando el Estado de Twitter desde mi propia aplicación Java</em>&#8216; podremos comprobar como en la cuenta de <strong>Twitter </strong>del usuario -en este caso, yo- el estado se ha modificado:
<p><div id="attachment_1387" class="wp-caption aligncenter" style="width: 639px"><img class="size-full wp-image-1387" src="http://sixservix.com/blog/david/files/2009/12/twitter2.jpg" alt="twitter2" width="629" height="367" /><p class="wp-caption-text">Fijaos en que pone que el estado se ha modificado desde &#39;Prueba David&#39; el nombre de mi aplicación registrada</p></div></li>
</ol>
<p style="text-align: justify">
<p style="text-align: justify">Si accedéis a la API de <strong>Twitter </strong>desde una aplicación web, podréis redirigir el flujo de la aplicación a la página de autenticación y configurar dicha página para que invoque una de vuestras páginas mediante <em>callback</em>. Mola ¿verdad? Se autentican en <strong>Twitter </strong>y continúan en tu aplicación proporcionándote el <strong>PIN </strong>de autenticación de paso.</p>
<p style="text-align: justify">Evidentemente <strong>esta aplicación es una chorrez como un piano</strong>, pero es un ejemplo claro y sencillo sobre cómo registrar una aplicación en Twitter, cómo autenticar a un usuario mediante <strong>OAuth </strong>y cómo manejar su <em>pool</em> de servicios<strong> </strong>en nombre de ese usuario. A partir de aquí, enriquecer y hacer crecer esta mini aplicación, depende de vosotros. Seguro que se os ocurren un montón de ideas, simplemente estudiando las posibilidades de la API, pero os voy a proponer algo: ¿No creéis que sería interesante para un departamento de marketing una aplicación que buscara menciones de los productos de una compañía en los <em>tweets </em>de la gente y que guardara los IDs de la gente para, posteriormente mandarles <a href="http://help.twitter.com/forums/82075/entries/72739" target="_blank"><em>tweets </em>de respuesta</a> con ofertas o comunicados? Yo, al menos, conozco a más de un <em>gurú del marketing</em> muuuy interesado :)</p>
<p style="text-align: justify">Espero que este humilde tutorial os haya servido de ayuda y os anime a crear la nueva <em>killer application</em> de esa pequeña gran plataforma llamada <strong>Twitter</strong>.</p>
<p style="text-align: justify"><span style="text-decoration: underline">Algunos <em>links </em>de interés</span></p>
<p style="text-align: justify"><span style="color: #008000"><strong>API REST DE TWITTER:</strong></span> <a href="http://apiwiki.twitter.com/Twitter-API-Documentation" target="_blank">http://apiwiki.twitter.com/Twitter-API-Documentation</a></p>
<p style="text-align: justify"><span style="color: #008000"><strong>API JAVA TWITTER4J:</strong></span> <a href="http://yusuke.homeip.net/twitter4j/en/javadoc/index.html" target="_blank">http://yusuke.homeip.net/twitter4j/en/javadoc/index.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2009/12/15/twitter-y-java/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>¿Habrá JavaOne en 2010?</title>
		<link>http://sixservix.com/blog/david/2009/12/09/javaone-2010/</link>
		<comments>http://sixservix.com/blog/david/2009/12/09/javaone-2010/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 06:30:59 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[javaone]]></category>
		<category><![CDATA[javaone10]]></category>
		<category><![CDATA[moscone center]]></category>
		<category><![CDATA[sun]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=1232</guid>
		<description><![CDATA[Uno de los principales damnificados de la fusión entre Oracle y SUN ha sido la conferencia anual javaOne, que se ha venido celebrando desde 1996.
Tradicionalmente, la javaOne ha sido la plataforma principal de SUN para difundir y expandir el lenguaje java y sus tecnologías asociadas. Sin embargo, la incertidumbre en la que están envueltos todos [...]


Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/09/07/agenda-javaone-2010/' rel='bookmark' title='Permanent Link: Mi agenda para la javaOne 2010'>Mi agenda para la javaOne 2010</a> <small>Esta es mi agenda preliminar para la edición 2010 de...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/07/23/javaone2010/' rel='bookmark' title='Permanent Link: javaOne 2010'>javaOne 2010</a> <small>David Bonilla se va de vacaciones pagadas a San Francisco...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-full wp-image-1233" style="margin-left: 3px;margin-right: 3px" src="http://sixservix.com/blog/david/files/2009/12/duke_j1.png" alt="duke_j1" width="160" height="186" />Uno de los principales damnificados de la fusión entre <strong>Oracle </strong>y <strong>SUN </strong>ha sido la conferencia anual <a href="http://en.wikipedia.org/wiki/JavaOne" target="_blank">javaOne</a>, que se ha venido celebrando desde 1996.</p>
<p style="text-align: justify">Tradicionalmente, la <strong>javaOne </strong>ha sido la plataforma principal de SUN para difundir y expandir el lenguaje java y sus tecnologías asociadas. Sin embargo, la incertidumbre en la que están envueltos todos los proyectos y actividades de la compañía de Santa Clara desde que comenzó el <a href="http://www.youtube.com/watch?v=mc20IkJjt_w" target="_blank">proceso de adquisición</a> por parte de Oracle, también ha atrapado a la conferencia, que tiene un incierto futuro. Por eso, muchos se preguntan: &#8220;<a href="http://javahispano.org/contenidos.item.action?id=5822540&amp;menuId=NEWS">¿Habrá una javaOne este año?</a>&#8220;.</p>
<p style="text-align: justify">Poco o nada se sabe de la <strong>javaOne </strong>de 2010, pero, la semana pasada, confeccionando un calendario de eventos para la planificación del próximo año,  <strong>conseguí encontrar algo de información</strong>.<span id="more-1232"></span></p>
<p style="text-align: justify">En <a href="http://www.moscone.com/site/do/event/view?nav.type=0&amp;nav.filter=1006&amp;nav.base=0912&amp;id=440" target="_blank">la web del Moscone Center</a>, el centro de conferencias de San Francisco donde se celebra la javaOne, aparece listado como <strong>evento confirmado del 22 al 25 de junio de 2010</strong>. Además, sigue existiendo una <a href="http://www.techpresentations.org/JavaOne_2010" target="_blank">web no oficial</a> donde, aquellos que deseen postularse como ponentes pueden mandar sus presentaciones técnicas. En esta web, las fechas que se ofrecen son del 21 al 24 de junio.</p>
<p style="text-align: justify">¿Significa esto que se confirma la celebración de la javaOne? Pues&#8230; NO. <span style="text-decoration: underline">El Moscone Center debe reservarse con hasta 18 meses de antelación</span>. Lo único que demuestra todo esto es que, <strong>hoy por hoy, SUN no ha cancelado la conferencia</strong>.</p>
<div id="attachment_1260" class="wp-caption alignright" style="width: 250px"><a href="http://sixservix.com/blog/david/files/2009/12/javaOne2.jpg"><img class="size-medium wp-image-1260 " style="margin-left: 5px;margin-right: 5px" src="http://sixservix.com/blog/david/files/2009/12/javaOne2-240x300.jpg" alt="javaOne2" width="240" height="300" /></a><p class="wp-caption-text">Con los chicos de Nosys, en la calle Lombard, el último día en San Francisco</p></div>
<p style="text-align: justify">En la web hay opiniones para todos los gustos: algunos creen que la javaOne va a seguir, otros piensan que se fusionará con el evento <strong>Oracle Open World</strong> y, los más pesimistas, temen que desaparezca.</p>
<p style="text-align: justify">Del mismo modo, la <strong>javaOne </strong>tiene detractores y partidarios. Entre los primeros, se encuentran todos aquellos que creen que <span style="text-decoration: underline">una conferencia <em>off-line</em> de esa magnitud es un anacronismo en la actualidad</span>, cuando toda la información está disponible en la red. Entre los segundos, me encuentro yo mismo, que puedo aportar <a href="http://javahispano.org/contenidos.item.action?id=2356658&amp;menuId=MINDS" target="_blank">mi experiencia como asistente en la pasada edición</a>.</p>
<p style="text-align: justify">Efectivamente, aunque la teoría dice que nada o poco se puede aprender que no se encuentre ya en la red,<strong> la realidad es muy distinta</strong>. <span style="text-decoration: underline">La javaOne es una oportunidad magnífica</span> para tomarte un descanso de tu día a día y dedicarte en exclusiva, durante una semana, a aprender, renovar tus conocimientos y empaparte del mundo java.</p>
<p style="text-align: justify">Además, la javaOne te <strong>permite conocer en persona a muchos de los miembros de la comunidad</strong> <strong>java</strong> que habitualmente  sigues o lees. Puedes leer páginas y páginas sobre <a href="http://sixservix.com/blog/david/2009/11/20/closuresyjava/" target="_blank"><em>closures </em>en java</a>, pero no es comparable al placer de hacerlo rodeado de colegas, tomando unas cervezas en el <a href="http://www.thirstybear.com/" target="_blank">Oso Sediento</a> a los pies del Moscone Center. <strong>La javaOne es algo diferente</strong>.</p>
<p style="text-align: justify">Si alguno tiene pensado <strong>asistir a la edición del próximo año</strong>, podéis poneros en contacto conmigo a través de <a href="http://sixservix.com/blog/david/about/" target="_blank">este formulario</a>. A ver si, entre todos, conseguimos arrebatar a <strong>los brasileños</strong> el título de nacionalidad <em>latina </em>más organizada&#8230; y ruidosa :)</p>
<p style="text-align: justify">Si el año pasado, la experiencia fue increíble, no me puedo ni imaginar como sería teniendo cerca a gente como <a href="http://jorgerubira.blogspot.com/" target="_blank">Rubirator</a>, el <a href="http://www.javahispano.org/contenidos/es/javahispano_podcast__006__itsnat_entrevista_a_jose_maria_arranz/" target="_blank">Profesor Arranz</a>, <a href="http://sixservix.com/blog/david/files/2009/12/jeroclo.jpg" target="_blank">Jeroclo el espartano</a>, <a href="http://albertovilches.com/" target="_blank">Beto Vilches</a> y tantos otros&#8230;</p>
<p style="text-align: justify">
<p style="text-align: justify">


<p>Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/09/07/agenda-javaone-2010/' rel='bookmark' title='Permanent Link: Mi agenda para la javaOne 2010'>Mi agenda para la javaOne 2010</a> <small>Esta es mi agenda preliminar para la edición 2010 de...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/07/23/javaone2010/' rel='bookmark' title='Permanent Link: javaOne 2010'>javaOne 2010</a> <small>David Bonilla se va de vacaciones pagadas a San Francisco...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2009/12/09/javaone-2010/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Llegan las closures a Java: el mundo se va a acabar</title>
		<link>http://sixservix.com/blog/david/2009/11/20/closuresyjava/</link>
		<comments>http://sixservix.com/blog/david/2009/11/20/closuresyjava/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 06:29:18 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[closures]]></category>
		<category><![CDATA[java 1.7]]></category>
		<category><![CDATA[jdk7]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=741</guid>
		<description><![CDATA[La repanocha. Ha llegado Mark Reinhold y, de improviso y sin avisar, ha anunciado en la Devoxx que la nueva versión 1.7 del lenguaje java soportará el uso de closures.
Madre mía&#8230; madre mía ¿Pero qué es eso de closures? Aunque los chicos de Groovy y Ruby que están en la onda y dominan el flow [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-full wp-image-743" style="margin-left: 5px;margin-right: 10px" src="http://sixservix.com/blog/david/files/2009/11/james_goslingc.jpg" alt="james_goslingc" width="240" height="204" />La repanocha. Ha llegado <a href="http://blogs.sun.com/mr/" target="_blank">Mark Reinhold</a> y, de improviso y sin avisar, ha anunciado en la <a href="http://sixservix.com/blog/events/2009/08/11/devoxx09/" target="_blank">Devoxx</a> que <span style="text-decoration: underline">la nueva versión 1.7 del lenguaje java soportará el uso de <strong><em>closures</em></strong></span>.</p>
<p style="text-align: justify">Madre mía&#8230; madre mía ¿Pero qué es eso de <em>closures</em>? Aunque los chicos de Groovy y Ruby que están <em>en la onda</em> y dominan el <em>flow </em>saben de que va el tema, a los arcaicos programadores-integristas de java, seguidores -como yo- de la Iglesia de San James Gosling de los Últimos Días, nos debería sonar a chino mandarino. En cualquier caso, debe de ser algo <strong>im-por-tan-tí-si-mo</strong> porque tiene a toda la comunidad revolucionada y hace que el mismísimo <a href="http://weblogs.javahispano.org/jh/entry/nos_presentamos_iii" target="_blank">Abraham Otero</a> de jH publique la <a href="http://javahispano.org/contenidos/es/al_final_parece_que_el_jdk_7_va_a_soportar_closures/?menuId=NEWS" target="_blank">noticia con nada menos que tres admiraciones !!!</a> Habrá que investigarlo.</p>
<p style="text-align: justify">Pues bien, las <em>closures</em> son, ni más ni menos, que bloques de código que, una vez definidos, puedes asignar a una  o más variables y ejecutar posteriormente. Por supuesto, estos bloques pueden recibir parámetros.<span id="more-741"></span></p>
<p style="text-align: justify">Antes de nada, hay que reconocer que la frase anterior es <strong>bastante densa</strong>, así que vamos a parar un momento para ver un código de ejemplo que nos ayude a comprenderla. De todos los ejemplos del mundo mundial de la vida vital que he podido encontrar en la red sobre <em>closures</em>, este <a href="http://blogs.msdn.com/kartikb/archive/2009/02/08/closures.aspx" target="_blank">pedazo de javascript</a> me parece el más sencillo y aclaratorio:</p>
<pre>function localise(greeting) {</pre>
<blockquote>
<pre>return function(name) { alert(greeting + ‘ ‘ + name };</pre>
</blockquote>
<pre>}</pre>
<pre>var english = localise(‘Hello’);</pre>
<pre>var french = localise(‘Bonjour’);</pre>
<pre>english(‘kartik’);                                 // alert box with “Hello kartik”</pre>
<pre>french(‘kartik’)                                   // alert box with “Bonjour kartik”</pre>
<p style="text-align: justify">
<p style="text-align: justify">Se que más de uno estará pensando <strong>&#8220;¿y para qué quiero yo utilizar esta memez?</strong>&#8221; No os quedéis en la superficie, pensad en las posibilidades. Por ejemplo, utilizad esas variables que apuntan a bloques de código como parámetros de un segundo método.</p>
<pre style="text-align: justify">login(name, password, english) // Devuelve un saludo en inglés si el usuario se autentica</pre>
<p style="text-align: justify">
<p style="text-align: justify">
<p style="text-align: justify"><img class="alignright size-full wp-image-772" style="margin-left: 10px;margin-right: 10px" src="http://sixservix.com/blog/david/files/2009/11/rodtequeremos.jpg" alt="rodtequeremos" width="230" height="199" />Si alguno se ha quedado con cara de Bugs Bunny y farfullando un &#8220;¿esto es todo amigos?&#8221; que no se preocupe porque, realmente, <strong>esto es todo amigos</strong>. <strong>Ni el mundo se va acabar ni de repente se van a resolver de forma mágica todos vuestros problemas</strong>. Vuestro Jefe de Proyecto no va a estar más contento porque las utilicéis, vuestra empresa no os va a pagar más y, desde luego, no vais a tener más éxito con las mujeres, pero puede que os permitan desarrollar vuestro trabajo mejor y más rápido.</p>
<p style="text-align: justify">Las <em>closures </em>son una herramienta más, que le da más potencia al lenguaje. Ni más, ni menos.</p>
<p style="text-align: justify">¿Qué se os ocurren mil y una formas de hacer lo mismo con otras herramientas de java como las clases internas o las interfaces? Pues, también. Pero no hay que ser más papistas que el Papa. El propio Gosling escribió en su blog que java no es algo que deba permanecer inmutable sino un lenguaje vivo que va evolucionando y reconoce que las <em>closures </em>se quedaron fuera de las primeras versiones más por<a href="http://blogs.sun.com/jag/entry/closures" target="_blank"> problemas de tiempos</a> que por otra cosa.</p>
<p style="text-align: justify">Le podemos dar más vueltas y buscar una explicación más exhaustiva o hablar sobre la posibilidad de utilizar variables locales que toman valor en la definición de la <em>closure </em>y no en la ejecución, pero no es el objetivo de este artículo.</p>
<p style="text-align: justify">Por último, advertiros de que podéis sorprenderos con un batiburrillo de siglas asociadas a esto de las <em>closures </em>como <strong>BGGA </strong>o <strong>CICE</strong>. No os preocupéis, solo sirven para identificar las <strong>propuestas de implementación</strong> que ha hecho determinada gente. Así, por ejemplo, <strong>BGGA </strong>surge de los apellidos del grupo de amigos que se reúnen para tomar cervezas y hablar de <em>closures </em>(<strong>Gilad Bracha</strong>, <strong>Neal Gafter</strong>, <strong>James Gosling</strong> y <strong>Peter von                         der Ahé</strong>).</p>
<p style="text-align: justify">Las <em>closures </em>llegarán con java 7. Bienvenidas sean, las estamos esperando.</p>
<p style="text-align: justify">
<h3 style="text-align: justify">RECURSOS</h3>
<p style="text-align: justify"><span style="color: #008000"><strong>Closures en Groovy:</strong></span> <a href="http://groovy.codehaus.org/Closures" target="_blank">http://groovy.codehaus.org/Closures</a></p>
<p style="text-align: justify"><span style="color: #008000"><strong>Excelente articulo sobre el tema en Javaworld:</strong></span> <a href="http://bit.ly/29e6Ih" target="_blank">http://bit.ly/29e6Ih</a></p>
<p style="text-align: justify"><span style="color: #008000"><strong>A James Gosling le gustan las <em>closures</em>:</strong></span> <a href="http://blogs.sun.com/jag/entry/closures" target="_blank">http://blogs.sun.com/jag/entry/closures</a></p>
<p style="text-align: justify"><span style="color: #008000"><strong>Otro sitio donde explican las <em>closures </em>de forma sencilla:</strong></span> <a href="http://bit.ly/1txbqG" target="_blank">http://bit.ly/1txbqG</a></p>
<p style="text-align: justify"><span style="color: #008000"><strong>Última Propuesta BGGA:</strong></span> <a href="http://www.javac.info/" target="_blank">http://www.javac.info/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2009/11/20/closuresyjava/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>CruiseControl vs. Hudson: la comparativa perfecta</title>
		<link>http://sixservix.com/blog/david/2009/11/19/cruisevshudson/</link>
		<comments>http://sixservix.com/blog/david/2009/11/19/cruisevshudson/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 15:04:52 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[comparativa]]></category>
		<category><![CDATA[cruise control]]></category>
		<category><![CDATA[hudson]]></category>
		<category><![CDATA[integracion continua]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=727</guid>
		<description><![CDATA[Una comparativa completa y resumida de dos servidores de integración continua: Hudson vs. Cruise Control]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">Evaluando un Servidor de Integración Continua para mi equipo me he encontrado con <a href="http://www.bigbeeconsultants.co.uk/cruise-control-vs-hudson" target="_blank">esta comparativa</a> entre <a href="http://cruisecontrol.sourceforge.net/" target="_blank">CruiseControl</a> y <a href="http://hudson-ci.org/" target="_blank">Hudson</a>.</p>
<p style="text-align: justify">Independientemente de las características de los dos productos, para mi es un ejemplo de <strong>comparativa perfecta</strong>: tabulada, clara, concisa, con anotaciones aclaratorias y un escueto resumen final, donde el autor &#8220;<strong>se moja</strong>&#8221; eligiendo una de las dos soluciones y razonando su elección. <strong>Impecable</strong>.</p>
<p style="text-align: justify"><a href="http://www.bigbeeconsultants.co.uk/cruise-control-vs-hudson" target="_blank">http://www.bigbeeconsultants.co.uk/cruise-control-vs-hudson</a></p>
<p style="text-align: justify">Otra comparativa muy buena, con una tabla no tan completa , pero&#8230; en español :)</p>
<p style="text-align: justify"><a href="http://xnoccio.com/372-conclusiones-finales-eligiendo-nuestro-entorno-de-integracion-continua-v/" target="_blank">http://xnoccio.com/372-conclusiones-finales-eligiendo-nuestro-entorno-de-integracion-continua-v/</a></p>
<p style="text-align: justify">
]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2009/11/19/cruisevshudson/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Explicando REST a mi madre</title>
		<link>http://sixservix.com/blog/david/2009/09/30/explicando-rest-a-mam/</link>
		<comments>http://sixservix.com/blog/david/2009/09/30/explicando-rest-a-mam/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 05:30:14 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[webservices]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=186</guid>
		<description><![CDATA[Si mamá, desde hace ya un buen tiempo, cuando vienes a visitarme a casa, no paras de leer en la pantalla de mi ordenador, en los papeles que tengo por ahí sueltos,  eso de REST. Y como no acabas de creerte que el término no tiene nada que ver con colchones, voy a intentar explicártelo.
Puedes [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-medium wp-image-279" style="margin: 5px 10px" src="http://sixservix.com/blog/david/files/2009/09/nerd-223x300.jpg" alt="CB009957" width="161" height="216" />Si mamá, desde hace ya un buen tiempo, cuando vienes a visitarme a casa, no paras de leer en la pantalla de mi ordenador, en los papeles que tengo por ahí sueltos,  eso de <strong>REST</strong>. Y como no acabas de creerte que el término <a href="http://www.bodyrestmattress.com" target="_blank">no tiene nada que ver con colchones,</a> voy a intentar explicártelo.</p>
<p style="text-align: justify">Puedes encontrar artículos en la web que describen <a href="http://www.dosideas.com/java/314-introduccion-a-los-servicios-web-restful.html" target="_blank">REST en castellano de pe a pa</a>, e incluso completísimos tutoriales sobre <a href="http://www.gruposp2p.org/wiki/index.php/Arranque_de_un_proyecto_con_Rest,_JPA_y_Maven" target="_blank">como montar tu primera aplicación REST con java</a>, pero quizás todo sea demasiado teórico y complejo para alguien que, como tú, busca una primera aproximación y no tiene porqué tener necesariamente mucha idea de Web Services, SOA o HTTP. Voy a intentar explicártelo muy claro y con ejemplos, como a ti te gusta.</p>
<p style="text-align: justify">Tranquila mamá, no te sientas mal por no tener muy claro esos conceptos. Hay muchos arquitectos de software y desarrolladores que tampoco los tienen. A lo mejor a ellos también les interesaría escuchar todo esto que te cuento. Es fácil, creo que en <strong>menos de 5 minutos</strong> tú y ellos os habréis hecho con ello.<span id="more-186"></span></p>
<p style="text-align: justify">Lo primero que tienes que tener claro es que <span style="text-decoration: underline">REST no es una tecnología sino una arquitectura</span>. Para que lo entiendas, no es algo que solucione cosas sino una forma de diseñar algo que solucione cosas. ¿Y qué tiene de especial esta <em>arquitectura </em>para que todo el mundo hable de ella? Intentaré explicártelo.</p>
<ol style="text-align: justify">
<li><strong>Diseñas tu aplicación exponiendo </strong><strong>recursos no funcionalidades</strong>. Sí, ya no programo páginas web que tengan direcciones como<em> www.mipagina.com/crearCosa</em> o <em>www.mipagina.com/consultarCosa</em>. Ahora sólo tengo <em>www.mipagina.com/cosas </em>o <em>www.mipagina.com/cosas/12345/atributos</em>. Sí te das cuenta, es como si tuviera mis recursos ordenados en directorios. Y sí, sé lo que te estás preguntando: si sólo hay un <em>www.mipagina.com/cosas </em>¿cómo sé si mis usuarios intentan crear una cosa o simplemente consultarla? Ahora te explico, ten un poco de paciencia.</li>
<li><strong>Utiliza los métodos del protocolo HTTP de manera explicita</strong>. HTTP es un protocolo de comunicación que hace que Internet funcione. ¿No te has dado cuenta de que cuando escribes una dirección en el navegador pone <em>http://</em> por delante de la dirección? Bueno, pues eso es porque te estás comunicando mediante ese protocolo. <span style="text-decoration: underline">Lo que no tanta gente sabe, incluidos muchos programadores</span>, es que el protocolo HTTP tiene un montón de métodos definidos en su especificación: GET, POST, PUT, DELETE&#8230; y que cada uno de ellos tiene un propósito específico aunque, a veces, te reconozco que los desarrolladores nos lo saltamos a la torera.  No te suena de nada ¿verdad? Eso es porque <span style="text-decoration: underline">la mayoría de los navegadores utilizan el método GET por defecto en las peticiones HTTP</span>, excepto que le indiquemos especificamente otra cosa en nuestras páginas web. Así , cuando escribimos el nombre de una página en la barra de direcciones de un navegador, la invocamos con el método GET. ¿Que por qué te he soltado este <em>ladrillo</em> que no te interesa? Espera un poco, ya verás como todo empieza a encajar.</li>
<li><strong>Mapea los métodos del protocolo HTTP a las operaciones a realizar sobre un recurso</strong>. Fíjate que bueno, si te conectas a un recurso -una página web, para que lo entiendas- invocando el método GET, por ejemplo, yo sé que es lo que quieres porque <span style="text-decoration: underline">el método GET se utiliza para consultar un recurso</span>. Del mismo modo, al resto de los métodos principales de HTTP se les mapea una operación específica. Así, POST se utiliza para crear un recurso, PUT para actualizarlo y DELETE para borrarlo, evidentemente. Si, por ejemplo, solicitas la página  <em>www.mipagina.com/cosas</em> con el parámetro id=2345 y el método GET, mi aplicación REST te devolverá la cosa con id=2345. Sin embargo, si repites la misma solicitud con el mismo parámetro pero con el método DELETE lo que  conseguirás es borrar la cosa con id=2345.  ¡Tacháaan! ¿A que ahora parece todo más claro?</li>
<li><strong>Transfiere XML, JSON o XTHML</strong>. No te voy a calentar la cabeza mamá explicándote qué es cada cosa. Confía en mi. Basta con que sepas que son cosas que se pueden consumir e interpretar desde un navegador y convertir en una de esas bonitas páginas web que tanto te gustan. Sólo para que lo sepas, cuando te digo que te <em>devuelve</em> una <em>cosa</em>, me refiero a que te devuelve algo como esto:</li>
</ol>
<pre style="padding-left: 60px;text-align: justify">&lt;cosa&gt;</pre>
<pre style="padding-left: 60px;text-align: justify">    &lt;id&gt;2345&lt;/id&gt;</pre>
<pre style="padding-left: 60px;text-align: justify">    &lt;nombre&gt;cosa misteriosa&lt;/nombre&gt;</pre>
<pre style="padding-left: 60px;text-align: justify">&lt;/cosa&gt;</pre>
<p style="text-align: justify">
<p style="text-align: justify">Sé que tendrás algunas dudas. Creo que podré adivinar alguna de ellas :)</p>
<ul style="text-align: justify">
<li><strong>¿Cómo le indico eso del id? ¿Sólo puedo mandar un parámetro? Y lo de los métodos HTTP ¿Cómo se cambian? </strong>Bueno, a ver, el id es un parámetro que envías en tu petición. Y, claro, puedes mandar todos los que quieras. Si lo piensas bien, cuando rellenas un formulario en una página web no estás haciendo más que mandar un montón de parámetros -uno por cada campo del formulario- sin límite alguno. Usando REST no haces mas que navegar así que, SÍ, puedes enviar lo que quieras. Respecto a lo de cambiar el método HTTP a utilizar bueno&#8230; eso no es tan sencillo. <span style="text-decoration: underline">No vas a poder hacerlo directamente desde tu navegador</span> pero, <span style="text-decoration: underline">los programadores de páginas HTML sí tienen la posibilidad de hacerlo</span>. Si llegas a una página web diseñada para utilizar con una aplicación REST y, por ejemplo, ves un botón &#8220;Eliminar <em>Cosa</em>&#8220;, seguro que vas a hacer una petición con el método DELETE</li>
<li><strong>¿Y si no le paso ningún parámetro?</strong> No pasa nada. Si, por ejemplo, haces una petición GET a <em>www.mipagina.com/cosas </em>sin pasar ningún parámetro, probablemente conseguirás que una aplicación REST te devuelva un montón de <em>enlaces</em> a todas las cosas que esten relacionadas con dicho recurso. Por ejemplo, una lista de cosas (<em>www.mipagina.com/cosas/0001, </em><em>www.mipagina.com/cosas/0002</em>&#8230;). Si lo piensas bien <span style="text-decoration: underline">todo lo que te devuelve son a su vez enlaces REST que puedes reutilizar haciendo nueva petición con el método que te interese</span> contra dichos enlaces. ¡Genial! ¿Verdad?</li>
<li><strong>¿Y todos los recursos implementan todos los métodos?</strong> Pues, realmente NO. De hecho, hay otro método de HTTP, <strong>OPTIONS</strong>, cuya finalidad es obtener una lista de los métodos soportados por un recurso. A lo mejor, el programador de una aplicación REST quiere permitirte consultar una determinado información pero no quiere que la actualices.</li>
<li><strong>Y entonces ¿cualquiera puede borrar cosas de tu aplicación?</strong> No. Puedes identificar a tus usuarios con los métodos de autenticación que te proporciona cualquier servidor HTTP o incluso utilizar <a href="http://developers.sun.com/identity/reference/techart/restwebservices.html" target="_blank">cosas más sofisticadas</a>.  No te preocupes, puedes conseguir que sólo acceda a tu aplicación REST quien tú quieras.</li>
</ul>
<p style="text-align: justify">Como ya te he dicho REST sólo es una arquitectura, no una tecnología. Tienes que evaluar bien si te interesa o no utilizarla. Si te interesa conocer cuáles son algunas de sus ventajas, te explicaré alguna de las más importantes:</p>
<ul style="text-align: justify">
<li><strong>El método HTTP GET y el cacheo</strong>. Muchos <em>proxies </em>y <em>firewalls </em>-ordenadores que gestionan una red- suelen cachear las peticiones GET. Que, ¿qué es eso de cachear? Pues guardarse una copia de la página que solicitas con tu método GET y, si otro ordenador de tu misma red solicita la misma página, devolver esa copia mucho más rápido que si tuviera que obtener la página de nuevo.</li>
<li><strong>No utiliza estado de sesión</strong>. A ver como te explico esto&#8230; ¿recuerdas cuando me pediste que te enseñara a comprar por Internet y estuvimos comprando libros? Esos libros se iban acumulando en un <em>carrito de la compra</em> y, al final, pagamos con tarjeta de crédito. Bueno, ese carrito de la compra existía porque la página web nos identificó durante toda nuestra<em> sesión de trabajo</em> y, es genial. Lo que pasa es que, al final, somos muchos los que compramos libros y eso puede acabar sobrecargando los servidores donde se alojan las páginas web. Cuando 5 están comprando libros no hay problema pero, cuando son 5000&#8230; la cosa cambia. El hecho de que REST no mantenga estado de sesión quiere decir que en nuestras peticiones de recursos y en las respuestas del servidor tiene que viajar toda la información necesaria. Nada se guarda en la memoria del servidor.</li>
<li><strong>Puedes distribuir una API completa de tu aplicación en un fichero de javascript</strong>. Mmmm&#8230; para que lo entiendas de una forma sencilla ¿conoces <a href="http://www.facebook.com" target="_blank">Facebook</a>, no?. Bueno, pues lo bueno de  <strong>Facebook</strong>, lo que ha hecho que triunfe tanto es que <span style="text-decoration: underline">ha posibilitado que terceros creen aplicaciones y las incrusten en la página</span>. Casi todas esas aplicaciones te permiten interactuar con tus contactos de Facebook, pero dichas aplicaciones no tienen acceso directo a la BBDD de la página web, sino a una API, un conjunto de utilidades, que proporciona Facebook y que permiten acceder, por ejemplo, a los amigos del usuario que está ejecutando la aplicación. Créeme, <span style="text-decoration: underline">eso es una aplicación REST como una casa</span>. ¿Te imaginas que Facebook tuviera que distribuir por ahí la ruta de acceso a su BBDD? ¿Te imaginas los problemas de seguridad y escalabilidad que supondría?</li>
</ul>
<p style="text-align: justify">En fin mamá, que REST está muy bien, pero es una manera más de solucionar las cosas, ni más ni menos. Por ejemplo, no tengo muy claro que fuera la arquitectura más adecuada para ese ejemplo que te he puesto del <em>carrito de la compra</em>, aunque sí para muchos otros supuestos.</p>
<p style="text-align: justify">La gente está muy ilusionada con el tema, sobre todo como <span style="text-decoration: underline">una apuesta para conseguir de una manera sencilla, rápida y flexible la interoperabilidad entre distintas aplicaciones escritas en distintos lenguajes</span>. Antes todo el mundo pensaba que los <strong>webservices </strong>eran el único medio válido para conseguir esto de una manera eficiente pero, ahora, hay bastante gente que lo pone en duda porque, la verdad, la especificación donde te explica cómo implementarte por entero un webservice, cómo publicarlo y cómo consumirlo es&#8230; un <strong>poco dura</strong> y pffff&#8230; ¡no creo que consiguiera explicártela en 5 minutos como he hecho con esto del REST! Y eso es lo bueno de esta arquitectura. Mamá, si tú has conseguido entenderlo, creo que cualquier desarrollador lo hará.</p>
<p style="text-align: justify">
]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2009/09/30/explicando-rest-a-mam/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Escuela de Groovy: llevando groovy a la empresa</title>
		<link>http://sixservix.com/blog/david/2009/09/16/escuela-de-groovy/</link>
		<comments>http://sixservix.com/blog/david/2009/09/16/escuela-de-groovy/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 14:42:10 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[escuela de groovy]]></category>
		<category><![CDATA[gant]]></category>
		<category><![CDATA[gorm]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[grape]]></category>
		<category><![CDATA[griffon]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=246</guid>
		<description><![CDATA[Hace unos días, durante una escala en el aeropuerto de Bangkok, tuve un interesante debate con Alberto Vilches sobre la adopción de groovy en el mundo del desarrollo de software corporativo en el que estoy inmerso. Al entusiasmo jedi de Alberto se contraponía mi escepticismo desde el punto de vista de la gestión, el lado [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><a href="http://www.escueladegroovy.com"><img class="alignleft size-full wp-image-247" style="margin-left: 5px;margin-right: 5px" src="http://sixservix.com/blog/david/files/2009/09/edg.jpg" alt="edg" width="300" height="110" /></a>Hace unos días, durante una escala en el aeropuerto de Bangkok, tuve un interesante debate con <a title="Alberto Vilches" href="http://albertovilches.com/category/tecnologia/javaprogramacion/" target="_blank">Alberto Vilches</a> sobre la adopción de groovy en el mundo del desarrollo de software corporativo en el que estoy inmerso. Al entusiasmo <em>jedi </em>de Alberto se contraponía mi escepticismo desde el punto de vista de la gestión, el <em>lado oscuro de la fuerza</em>. Nadie discute lo bueno de groovy ni todo lo que aporta pero ¿tiene cabida en proyectos de tamaño medio y grande? ¿De verdad Grails vale para algo más que hacer webs sencillitas del tipo &#8220;Recauchutados López&#8221;? ¿Hay una oferta suficiente de personal formado? ¿La <em>libertad </em>que da no puede implicar agujeros del tamaño de Oceanía en proyectos de 20 a 25 programadores con un índice de rotación alto? ¿Qué le aportará a mi equipo de desarrollo? ¿Cuál será el retorno de inversión que obtendré por formar a un técnico en este lenguaje en vez de certificarle en JBoss, por ejemplo? Nuestro avión llegó antes de que llegáramos a alguna conclusión.</p>
<p style="text-align: justify">Para obtener respuesta a todas estas preguntas nace <a href="http://www.escueladegroovy.com/" target="_blank">Escuela de Groovy</a> la iniciativa impulsada por Nacho Brito y Álvaro Sánchez-Mariscal para introducir groovy en el mundo empresarial. El próximo 25 de septiembre se celebrará su puesta de largo en La Catedral, el centro de <a href="http://www.madridonrails.com" target="_blank">Madrid on Rails</a>.</p>
<p style="text-align: justify"><span id="more-246"></span>Al frente de <strong>Salenda </strong>e <strong>ImaginaWorks</strong>, Álvaro y Nacho han sido unos de los máximos impulsores de groovy en España y han celebrado múltiples cursos y ponencias gratuitas con el ánimo de formar a la comunidad y extender el uso del lenguaje entre la comunidad de desarrolladores Java. <strong>Escuela de Groovy</strong> recoge estos esfuerzos y los potencia mediante servicios de evangelización, oficina técnica, desarrollo y formación a medida, con el objetivo de convertirse en el referente de groovy en este país.</p>
<p style="text-align: justify">Le deseo a <strong>Escuela de Groovy </strong>un futuro lleno de éxitos, no sólo por su apoyo a las metodologías ágiles y las tecnologías abiertas y por el trabajo de Álvaro y Nacho a lo largo de estos años sino, sobre todo, por el  esfuerzo, valor e iniciativa que supone emprender en estos tiempos (y en estos parajes).</p>
<p style="text-align: justify">Si deseas asistir a su presentación y aprender más sobre las posibilidades de groovy en el mundo de la empresa, puedes apuntarte aquí:</p>
<p style="text-align: justify"><a href="http://escueladegroovy.stagehq.com/events/52"><img class="aligncenter size-full wp-image-253" src="http://sixservix.com/blog/david/files/2009/09/banner-presentacion180x292.jpg" alt="banner-presentacion180x292" width="180" height="292" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2009/09/16/escuela-de-groovy/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
