<?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; desarrollo</title>
	<atom:link href="http://sixservix.com/blog/david/category/desarrollo/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>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>Usando &#8216;&nbsp;&#8217; en XHTML</title>
		<link>http://sixservix.com/blog/david/2010/08/18/nbsp-en-xhtml/</link>
		<comments>http://sixservix.com/blog/david/2010/08/18/nbsp-en-xhtml/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 04:50:02 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[jsf]]></category>
		<category><![CDATA[nbsp]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=3976</guid>
		<description><![CDATA[
Todos los que hemos trabajado con páginas y aplicaciones web conocemos la entidad &#38;amp;nbsp; o, al menos, creemos conocerla&#8230; Pero, sorprendentemente, la mayoría de nosotros no sabemos qué es exactamente y eso hace que aparezcan problemas en la transición desde HTML hacia XTHML.
¿Queréis enteraros de qué es eso de &#38;amp;nbsp;  en apenas cinco minutos, mientras [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-full wp-image-3978" style="margin-right: 15px;margin-bottom: 15px" title="xhtml" src="http://sixservix.com/blog/david/files/2010/08/xhtml.gif" alt="XHTML, ese lenguaje" width="207" height="207" /></p>
<p style="text-align: justify">Todos los que hemos trabajado con páginas y aplicaciones web conocemos la entidad<strong> </strong><strong>&amp;amp;nbsp;</strong> o, al menos, creemos conocerla&#8230; Pero, sorprendentemente, la mayoría de nosotros no sabemos qué es exactamente y eso hace que aparezcan problemas en<strong> la transición desde HTML hacia XTHML</strong>.</p>
<p style="text-align: justify">¿Queréis enteraros de qué es eso de <strong>&amp;amp;nbsp;</strong><strong> </strong> en apenas cinco minutos, mientras leéis una <strong>apasionante historia de intriga y misterio</strong>? Entonces, no lo dudéis y seguid leyendo&#8230;</p>
<h3 style="text-align: justify">EL MISTERIO DE LA JSPX DESESTRUCTURADA</h3>
<p style="text-align: justify">Hace poco que empecé a sacar algo de tiempo libre para aportar al desarrollo  puro y duro de <a href="http://sixservix.com/es/storetto.php" target="_blank">STORETTO</a>. Al instalar el entorno de trabajo en Eclipse,  casi me caigo de la silla golpeado por un error rojo y horrible que señalaba a una <a href="http://en.wikipedia.org/wiki/Jspx" target="_blank">JSPX</a> traidora y maligna donde, según el IDE, había errores en la estructura del XML, la etiqueta de cerrado &#8216;<strong>&lt;/h:form&gt;</strong>&#8216; no se correspondía con ninguna etiqueta de apertura.</p>
<p style="text-align: justify">Cuando les pregunté a los desarrolladores por qué daba el error, me dijeron que era un error de Eclipse porque <strong>la estructura XML de la página estaba bien, </strong>funcionaba y la famosa etiqueta &#8216;<strong> </strong><strong>&lt;/</strong><strong>h:form</strong><strong>&gt;</strong>&#8216; tenía su correspondiente etiqueta de apertura.</p>
<p style="text-align: justify">¡Tenían razón! Entonces&#8230; ¿Qué estaba ocurriendo? ¿Qué era lo que estaba rompiendo el <em>Chi </em>del <strong>Eclipse</strong>? Era un claro caso para Bonilla Holmes&#8230;</p>
<h3 style="text-align: justify">LO MALO DE UN ECLIPSE, ES QUE NO TE DEJA VER</h3>
<p style="text-align: justify">Cuando oficialmente eres Jefe de Equipo, <em>Project Manager</em> o <em>Code Leader</em>, te puedes permitir ciertas licencias, como pararte a ver porqué algo falla aunque el error no sea crítico, que casi compensa el horrible título con el que definen tu puesto.</p>
<p style="text-align: justify">Así que me enfrenté al error con valentía y decisión. Era evidente que el el Eclipse fallaba a la hora de analizar la estructura de la página, la pregunta era: ¿Por qué?.</p>
<p style="text-align: justify">Al principio pensé que era por un código comentado que incluía la etiqueta en cuestión, pero lo borré y el error seguía. La cosa se ponía difícil, pero, entonces, observé un montón de <em>errorcillos</em> (perdonad por mi léxico, no soy un experto en Eclipse, yo soy más de <a href="http://www.jetbrains.com/idea/" target="_blank">IDEA</a>) provocados por el uso de la extraña combinación de caracteres &#8216;<strong>&amp;amp;amp;nbsp;</strong>&#8216;.</p>
<p style="text-align: justify">¿Para qué diantres estábamos <em>escapando </em>el carácter <strong>&amp;</strong> para, a su vez, <em>escapar</em> el carácter <strong>espacio</strong>? No tenía sentido. Cuando lo cambié a <strong>&amp;amp;nbsp;</strong> sin más, <span style="text-decoration: underline">el error de estructura en Eclipse dejó de aparecer</span>, pero la página daba un error al cargarse. No un error de maquetación, sino en la compilación en servidor.</p>
<p style="text-align: justify">Raro, raro, raro&#8230;</p>
<p style="text-align: justify">Cuando volví a preguntar a los desarrolladores si tenían idea alguna de por qué podía fallar la carga de la página web, me dijeron que no tenían ni idea pero que, por algún motivo, JSF -el <em>framework </em>que utilizamos- no se comía directamente el <strong>&amp;amp;nbsp;</strong> y, por eso, teníamos que escapar el carácter <strong>&amp;</strong> utilizando<strong> </strong><strong>&amp;amp;amp;</strong><strong>.</strong></p>
<h3 style="text-align: justify"><img class="alignright size-full wp-image-4023" style="margin-left: 10px" title="XHTML" src="http://sixservix.com/blog/david/files/2010/08/XHTML.jpg" alt="HTML en estado puro" width="200" height="200" />ELEMENTAL, QUERIDO WATSON</h3>
<p style="text-align: justify">No tenía sentido. Una cosa es que al tocar la página web descoyuntara la maquetación y otra cosa es que  rompiera el código del servidor. No comprendía muy bien qué tenía que ver JSF con los caracteres de escape del código HTML, así que le pedí al tío que más sabe de JSF a este lado del Pecos, <a href="http://sixservix.com/blog/cvivero/" target="_blank">César Vivero</a>, que mirara conmigo las trazas de servidor.</p>
<p style="text-align: justify">No nos hizo falta más de 10 segundos para localizar el error -&#8221;<em>The entity &#8220;nbsp&#8221; was referenced, but not declared.</em>&#8220;- e, inmediatamente, mi mente de <a href="http://www.astracanada.net/2010/04/04/5-mitos-sobre-los-viejos-programadores/" target="_blank">viejo rockero</a> sufrió un espectacular <em>flashback </em>peliculero cuando recordé que había tenido el mismo problema al trabajar con <strong>hojas de estilo XSLT que producían HTML</strong>.</p>
<p style="text-align: justify">Miré a mi compañero y le dije &#8220;<em>Lo tenemos César. Ya sé quién mató a Laura Palmer</em>&#8220;.</p>
<h3 style="text-align: justify">EL HTML NO ES XML, Y XHTML TAMPOCO</h3>
<p style="text-align: justify"><strong>El error en servidor no lo daba el uso de JSF en sí, sino el validador del XML de la página web</strong>. Sí, amigos, porque nuestras páginas son JSPX, lo cual quiere decir que utilizan XML y XHTML como lenguaje de marcas, no HTML&#8230; y ahí estaba el problema.</p>
<p style="text-align: justify"><strong>&amp;amp;nbsp;</strong> es <a href="http://www.sightspecific.com/~mosh/WWW_FAQ/nbsp.html" target="_blank">una entidad</a> <span style="text-decoration: underline">usada para representar el carácter espacio <strong>en HTML</strong>, pero no en XML</span>. Aunque a veces se nos olvide y haya cierta confusión al respecto porque algunas de las entidades, como la utilizada para representar el carácter &#8216;<strong>&amp;</strong>&#8216; -<strong>&amp;</strong><strong>amp;amp;</strong>- sean idénticas, <span style="text-decoration: underline"><strong>l</strong><strong>as entidades de caracteres en XML y HTML no son iguales</strong></span>.</p>
<p style="text-align: justify">Así, lo que está cantando el validador de XML es, traducido al cristiano, &#8220;<em>no sé qué me estás contando, brother</em>&#8220;. Y eso es así porque <strong>&amp;amp;nbsp;</strong><strong> </strong>para XML no es absolutamente NADA. El carácter espacio en XML es <strong>&amp;amp;nbsp;</strong> o, lo que es lo mismo, el carácter 160 de UNICODE.</p>
<p style="text-align: justify">Este <em>error</em> trivial es relativamente normal ya que, muchas veces, los desarrolladores trabajan directamente con una maqueta en HTML proporcionada directamente por un diseñador y la adaptan al lenguaje de plantillas correspondiente para que en java acabe siendo una JSP -con HTML incrustado- o una JSPX con XHTML.</p>
<h3 style="text-align: justify">UNA SOLUCIÓN QUIERO&#8230;</h3>
<p style="text-align: justify">Para poder solucionar este problema tenemos dos posibilidades:</p>
<p style="text-align: justify">1. Utilizar el DOCTYPE al comienzo de nuestra página XHTML para que identifique la entidad <strong>&amp;amp;nbsp;</strong> tal y como se especifica en <a href="http://msdn.microsoft.com/es-es/library/ms256059%28VS.80%29.aspx" target="_blank">este enlace</a>:</p>
<p style="text-align: justify">Por ejemplo, para una página XHTML cuyo nodo raíz es <em>jsp:root</em>, escribiríamos:</p>
<p style="text-align: justify">&lt;!DOCTYPE jsp:root [<br />
&lt;!ENTITY nbsp "<strong>&amp;amp;nbsp;</strong>"&gt;<br />
]&gt;</p>
<p style="text-align: justify">2. Haciendo una sustitución masiva de la entidad <strong>&amp;amp;nbsp; </strong> por la entidad <strong>&amp;amp;#160 </strong>que <span style="text-decoration: underline">sí es una entidad reconocida en XML</span>.</p>
<p style="text-align: justify">Lo que nunca descubrimos fue por qué Eclipse se volvía loco, pero el <em>chi</em> de los programadores ahora descansa tranquilo porque la pestaña de avisos y errores ya no muestra ninguna inquietante aspa roja. El misterio de la JSPX desestructurada había sido resuelto.</p>
<p style="text-align: justify">
<p style="text-align: justify">
<p style="text-align: justify">
<p style="text-align: justify">
<p style="text-align: justify">
]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/08/18/nbsp-en-xhtml/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Si los lenguajes fueran herramientas&#8230;</title>
		<link>http://sixservix.com/blog/david/2010/07/23/lenguajes-herramientas/</link>
		<comments>http://sixservix.com/blog/david/2010/07/23/lenguajes-herramientas/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 04:50:31 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[humor]]></category>
		<category><![CDATA[9GAG]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=3537</guid>
		<description><![CDATA[Si los lenguajes de programación fueran herramientas, podrían verse de esta forma... o al menos eso es lo que piensan los chicos de 9Gag :)]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">Si los lenguajes de programación fueran herramientas de desarrollo, podrían verse de la siguiente forma&#8230; o al menos eso es lo que piensan los chicos de <strong>9gag</strong>.</p>
<p style="text-align: justify">Una más de esas clasificaciones estúpidas del tipo &#8220;Como ven los Sistemas Operativos los <em>fans </em>de Haskell&#8221;. Eso si, si <a href="http://www.python.org/" target="_blank">Python</a> es una sierra mecánica, ya estoy tardando en aprenderlo. Mataría por que me regalaran una por mi cumple&#8230; ;)</p>
<p style="text-align: center"><a href="http://sixservix.com/blog/david/files/2010/07/28126_540.jpg"><img class="size-full wp-image-3539  aligncenter" style="border: 0pt none" title="28126_540" src="http://sixservix.com/blog/david/files/2010/07/28126_540.jpg" alt="" width="540" height="806" /></a></p>
<p>RT @<a href="http://9gag.com/photo/28126_540.jpg" target="_blank">9gag</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/07/23/lenguajes-herramientas/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Técnica Pomodoro Extrema</title>
		<link>http://sixservix.com/blog/david/2010/07/20/tecnica-pomodoro-extrema/</link>
		<comments>http://sixservix.com/blog/david/2010/07/20/tecnica-pomodoro-extrema/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 04:50:47 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[agile]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[gestion de personal]]></category>
		<category><![CDATA[concentrate]]></category>
		<category><![CDATA[extreme pomodoro technique]]></category>
		<category><![CDATA[scrum]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=3570</guid>
		<description><![CDATA[Como utilizar la Técnica Pomodoro para llegar donde nadie ha llegado. Trucos y buenas prácticas del gurú del Pomodoro: David Bonilla


Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/07/13/no-sabes-nada-de-la-tecnica-pomodoro/' rel='bookmark' title='Permanent Link: No sabes nada de la Técnica Pomodoro'>No sabes nada de la Técnica Pomodoro</a> <small>¿Conoces la Técnica Pomodoro? ¿CREES que conoces la Técnica Pomodoro?...</small></li>
<li><a href='http://sixservix.com/blog/david/2009/11/26/la-tecnica-pomodoro/' rel='bookmark' title='Permanent Link: La Técnica Pomodoro'>La Técnica Pomodoro</a> <small>Voy a intentar explicar de una forma divertida y amena...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-full wp-image-3584" title="pomodoro-technique" src="http://sixservix.com/blog/david/files/2010/07/pomodoro-technique.jpg" alt="Pomodoro Technique" width="223" height="323" />Si la semana pasada escribí sobre <a href="http://sixservix.com/blog/david/2010/07/13/no-sabes-nada-de-la-tecnica-pomodoro/" target="_blank">como utilizar (bien) la Técnica Pomodoro</a> para ayudar a aquellos que podían haber confundido la finalidad de la misma, hoy voy a presentar algunos trucos y buenas prácticas para llegar hasta los limites la Técnica Pomodoro.</p>
<p style="text-align: justify">Vamos a echarle un poco de chile picante a nuestra salsa de tomate. Hoy hablaremos sobre como practicar la <strong>Técnica Pomodoro Extrema</strong>.</p>
<h3>1. PROTÉGETE DE TI MISMO Y BLINDA TUS <em>POMODOROS</em></h3>
<p style="text-align: justify">Seamos sinceros. Si fuéramos capaces de concentrarnos como <strong>Kasparov</strong> batallando contra <strong>Deep Blue </strong>no estaríamos leyendo este artículo. Si utilizamos la Técnica Pomodoro es porque hemos llegado a la conclusión de que queremos y PODEMOS ser más productivos concentrándonos en una única tarea, evitando distracciones externas y, sobre todo, internas.</p>
<p style="text-align: justify">Dejemonos de eufemismos ¿Qué es eso de &#8216;<em>distracciones internas</em>&#8216;? Fácil: <strong>Twitter</strong>, <strong>Facebook</strong>, <strong>Spotify</strong>, navegar por Internet sin rumbo definido, correos electrónicos corporativos, correos electrónicos personales (véase <strong>Gmail</strong> o <strong>Hotmail</strong>), lectores de noticias y, la peor de todas: este adictivo <em>blog</em>.</p>
<p style="text-align: justify">¿Qué tienen en común todas estas actividades? Que se realizan frente al ordenador y, por lo tanto, son <em>disimulables</em> en un entorno laboral y que&#8230; requieren Internet.</p>
<p style="text-align: justify">Localizado el problema, encontrada la solución. En el mundo Apple, existe la <em>killer-app</em> con la que siempre soñaste: <a href="http://getconcentrating.com/" target="_blank">Concentrate</a> (no, no me he olvidado el acento, se pronuncia <em>consentreit</em>). <strong>Concentrate</strong> te permite bloquear, durante un tiempo determinado, aplicaciones, páginas webs, específicas, cambiar el estado del iChat poniendote como &#8216;No Disponible&#8217; y hasta lanzar <em>scripts</em> de <strong>AppleScript</strong>, lo que te permite hacer prácticamente lo que te de la gana (imaginaros las posibilidades para, por ejemplo, registrar tu histórico de <em>pomodoros</em> reales). Por supuesto, también te permite configurar cualquier tipo de alarmas y sonidos para ayudarte a concentrarte; y hasta finalizar con un &#8220;<em>¡Eres un figura!</em>&#8220;  con el que premiar tu esfuerzo.</p>
<p style="text-align: justify">En el mundo Windows no sé si existe algo tan <em>glamouroso</em> (por favor, si existe, hacedmelo saber) pero, siempre puedes <strong>tirar del cable de red</strong> y quedarte a solas con tu IDE, tu Tomcat y tu base de datos en local durante 25 minutos.</p>
<h3>2. COMPARTE TUS TO-DO TODAY</h3>
<p style="text-align: justify">Hemos dicho que la Técnica Pomodoro <strong>es una técnica de productividad personal</strong>.  No  intentes gestionar un equipo utilizando artefactos de la misma  como  los <em>To-Do Today</em> o el <em>Active Inventory</em>. No funciona.</p>
<p style="text-align: justify">Pero SI funciona -y bastante bien, por cierto- en combinación con otras técnicas ágiles de  gestión de  equipos o proyectos como, por ejemplo, <strong>Scrum</strong>. Y una de las máximas de Scrum es la <strong>TRANSPARENCIA</strong>. El razonamiento es: &#8220;&#8230; si estoy haciendo las cosas bien. Si estoy haciendo las cosas lo mejor que puedo <strong>¿Por qué tendría que ocultar algo?</strong>&#8220;. Desde hace algún tiempo, lo primero que hago al llegar al trabajo por las mañanas es escanear mi hoja de tareas del dia anterior<em> </em>y copiarla en un directorio compartido de mi ordenador.</p>
<p style="text-align: center">
<div id="attachment_3660" class="wp-caption aligncenter" style="width: 522px"><img class="size-full wp-image-3660 " title="chili-sauce" src="http://sixservix.com/blog/david/files/2010/07/chili-sauce.jpg" alt="" width="512" height="306" /><p class="wp-caption-text">Poniéndole un poco de picante a nuestros Pomodoros... La Técnica Pomodoro extrema</p></div>
<p style="text-align: justify">Cualquiera puede verlas, cualquiera puede ver lo que he hecho y cuanto tiempo teórico me ha costado. Algunos pensaréis que es algo redundante con otros artefactos de <strong>Scrum</strong> como el <em>Scrum Daily</em> pero, yo no lo veo así, sino como algo complementario. Mientras que en el <em>Scrum Daily</em> se responden a tres preguntas básicas ¿Que hice ayer? ¿Que voy a hacer hoy? ¿Que me impide ser más productivo?, en mi hoja de tareas se puede ver, si he conseguido completar <em>pomodoros</em>, el trabajo que dediqué a una tarea u a otra y, en el caso de que no lo haya conseguido, el nivel de <em>taladramiento</em> exterior o ensoñación interior que he sufrido (recordar que en la Técnica Pomodoro se registran de forma distinta las interrupciones internas y las externas).</p>
<p style="text-align: justify">Mi responsable no me pidió que lo hiciera, la gente de la que soy responsable tampoco. Lo he hecho de forma voluntaria y me ha ayudado a ser más constante en la aplicación de la Técnica y del registro de <em>pomodoros</em>, interrupciones y eventos inesperados en mi hoja diaria de tareas.</p>
<h3>3. PLANIFICA CON POMODOROS</h3>
<p style="text-align: justify">Yo suelo planificar todas mis tareas diarias en base a la duración en <em>pomodoros</em> de las mismas. Se que <strong>es difícil que pueda hacer más de 12 <em>pomodoros</em> al día</strong>. No es una buena ni una mala marca (recordar, esto no es una competición), es mi ritmo de trabajo habitual adaptado a la realidad de mi día a día.</p>
<p style="text-align: justify">Al principio se hace un poco raro pero, poco a poco, te vas acostumbrando. Dos <em>pomodoros</em> son 50 minutos de trabajo puro y, si crees que algo va a durar menos de un <em>pomodoro</em>, lo agrupas. Al final, te encuentras con agrupaciones de 3 llamadas de teléfono de esas que &#8220;<em>no puedes dejar de hacer</em>&#8221; o con <em>pomodoros</em> destinados a &#8220;<em>contestar correo</em>&#8220;. Una vez más, todo destinado a incrementar tu productividad.</p>
<p style="text-align: justify">La propia Técnica Pomodoro te sugiere que planifiques la duración de tus tareas en <em>pomodoros</em> y habla de un supuesto <em>Record Sheet</em> para poder comprobar las diferencias entre tus estimaciones y la realidad. No encontré ningún <em>Record Sheet </em>por ningún lado, así que <a href="http://sixservix.com/blog/david/2010/02/03/tecnica-pomodoro-record-sheet/" target="_blank">creé el mio</a> para poder registrar las diferencias de planificación.</p>
<p style="text-align: justify">Si <strong>Scrum ayuda al equipo a saber planificarse mejor en iteraciones de cierta duración</strong>, la Técnica Pomodoro puede ayudarte a planificar con más exactitud de la que creias posible el trabajo de tu dia a dia.</p>
<h3>4. DOMINA LA TÉCNICA POMODORO, NO DEJES QUE TE DOMINE A TI</h3>
<p style="text-align: justify">Un <a href="http://sixservix.com/blog/david/2010/07/13/no-sabes-nada-de-la-tecnica-pomodoro/#IDComment86454092" target="_blank">comentario del gran Xavi Gost</a> me hizo ver lo dogmático que puedo sonar pero, no soy un talibán de la estricta observancia de la Técnica Pomodoro por el contrario, creo que cada uno puede y debe adaptarla a si mismo y su forma de trabajo. El  manual donde Francesco Cirillo está muy bien y ¡es gratis! pero  no es la  Biblia. Francesco se limita a describir los conceptos básicos  de su  técnica y como aplicarlos.</p>
<p style="text-align: justify">En el  momento de redacción de este artículo, la última versión  disponible  era la 1.3, publicada el 15 de junio de 2007 o, lo que es lo  mismo, <strong>hace  más de tres años</strong>.</p>
<p style="text-align: justify">El  libro tiene algunas lagunas como la del <em>Record Sheet</em> que antes os he mencionado y, por   otro lado, al ser un manual, muchas veces se limita a describir reglas   sin explicar en profundidad el espíritu de las mismas lo que puede   llevar a confusiones.</p>
<p style="text-align: justify">En  cualquier caso, la Técnica Pomodoro es una técnica de  productividad  personal y, por tanto, debe y puede adaptarse a las  circunstancias  personales de cada uno para alcanzar su objetivo  principal: que seamos  más productivos. <strong>El manual es el inicio, no un  fin en si mismo</strong>.</p>
<p style="text-align: justify">Si por vuestra forma de trabajar os viene mejor hacer <em>pomodoros</em> de 47 minutos o intercaláis el trabajo entre dos tareas porque con una sola os <em>aburrís</em> y <strong>os funciona</strong>&#8230; ¡Genial! Lo importante es que consigáis más del tiempo que destinéis al trabajo.</p>
<p style="text-align: justify">&#8230;</p>
<p style="text-align: justify">Estos son sólo algunos consejos y buenas prácticas que a mi me han funcionado. Espero que podáis aplicarlos y, si os dan resultado, destinar algún <em>pomodoro</em> para dejar un comentario y contármelo. Os lo agradeceré de corazón. Muchas gracias por leerme.</p>


<p>Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/07/13/no-sabes-nada-de-la-tecnica-pomodoro/' rel='bookmark' title='Permanent Link: No sabes nada de la Técnica Pomodoro'>No sabes nada de la Técnica Pomodoro</a> <small>¿Conoces la Técnica Pomodoro? ¿CREES que conoces la Técnica Pomodoro?...</small></li>
<li><a href='http://sixservix.com/blog/david/2009/11/26/la-tecnica-pomodoro/' rel='bookmark' title='Permanent Link: La Técnica Pomodoro'>La Técnica Pomodoro</a> <small>Voy a intentar explicar de una forma divertida y amena...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/07/20/tecnica-pomodoro-extrema/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>No sabes nada de la Técnica Pomodoro</title>
		<link>http://sixservix.com/blog/david/2010/07/13/no-sabes-nada-de-la-tecnica-pomodoro/</link>
		<comments>http://sixservix.com/blog/david/2010/07/13/no-sabes-nada-de-la-tecnica-pomodoro/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 04:50:06 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[agile]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[gestion de personal]]></category>
		<category><![CDATA[pomodoro technique]]></category>
		<category><![CDATA[productividad]]></category>
		<category><![CDATA[scrum]]></category>
		<category><![CDATA[técnica pomodoro]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=3548</guid>
		<description><![CDATA[¿Conoces la Técnica Pomodoro? ¿CREES que conoces la Técnica Pomodoro? Sigue leyendo, puede que te sorprendas al descubrir cosas que nadie cuenta...


Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/07/20/tecnica-pomodoro-extrema/' rel='bookmark' title='Permanent Link: Técnica Pomodoro Extrema'>Técnica Pomodoro Extrema</a> <small>Como utilizar la Técnica Pomodoro para llegar donde nadie ha...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/02/03/tecnica-pomodoro-record-sheet/' rel='bookmark' title='Permanent Link: Técnica Pomodoro: Record Sheet'>Técnica Pomodoro: Record Sheet</a> <small>Cada vez somos más los que seguimos la Técnica Pomodoro...</small></li>
<li><a href='http://sixservix.com/blog/david/2009/11/26/la-tecnica-pomodoro/' rel='bookmark' title='Permanent Link: La Técnica Pomodoro'>La Técnica Pomodoro</a> <small>Voy a intentar explicar de una forma divertida y amena...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-medium wp-image-3549" style="margin-right: 10px" title="pomodoro_extremo" src="http://sixservix.com/blog/david/files/2010/07/pomodoro_extremo-185x300.jpg" alt="" width="185" height="300" />Voy a revelaros algo que puede ser traumático para muchos de vosotros: la mayoría no tenéis ni idea de qué es <a href="http://sixservix.com/blog/david/2009/11/26/la-tecnica-pomodoro/" target="_blank">la Técnica Pomodoro</a>.</p>
<p style="text-align: justify">Afirmar que se conoce la técnica por saber que &#8220;<em>es eso de trabajar 25 minutos y descansar 5</em>&#8221; es la misma tontería que decir que se conoce la gastronomía española por haber comido paella y sangría en un chiringuito de Ibiza&#8230; o decir que se domina <strong>scrum </strong>por <a href="http://sixservix.com/blog/david/2010/04/27/scrum-master/" target="_blank">tener un papel</a> que dice que uno es <em>Certified Scrum Master</em>.</p>
<p style="text-align: justify">Puede que algunos halláis ido aún más allá y leyerais todo el manual de <strong>Francesco Cirillo</strong> en perfecto inglés pero, creedme, si no habéis trabajado en la práctica con la Técnica Pomodoro, no tenéis ni idea de que va todo esto.</p>
<p style="text-align: justify">En este artículo aclararé algunos conceptos para los que acaban de descubrir  horrorizados que no se han enterado muy bien de que va todo esto e intentaré  evitaros algunos errores de concepto que corregí después de meses de pegarme con la Técnica Pomodoro.</p>
<h3>1.  ¡ESTO NO ES UNA COMPETICIÓN, ESTÚPIDO!</h3>
<p style="text-align: justify">Al principio, cuando comienzas a trabajar con la Técnica Pomodoro, crees que el hecho de hacer más o menos pomodoros indica lo mucho o poco que has trabajado. Eso es más falso que un billete de 7 euros.</p>
<p style="text-align: justify">El objetivo de la Técnica Pomodoro no es que hagas todos los <em>pomodoros </em>que puedas sino todas las tareas que puedas,  utilizando conceptos de otras metodologías de trabajo como el <strong>Getting Things Done</strong> y su lista de tareas o el <strong>Work In Progress</strong> y su apuesta por reducir al mínimo el trabajo en paralelo con varias tareas. Los <em>pomodoros</em>, porciones de tiempo de 25 minutos reservados en exclusiva a una tarea, son una herramienta para conseguirlo, no el fin en sí mismo. Aunque parezca increíble, la gente se olvida de esto.</p>
<p style="text-align: justify">Al final del día, puedes haber concluido todas tus tareas sin haber conseguido finalizar ni un solo pomodoro. De la misma forma, puedes haber cerrado 28 pomodoros y no haber finalizado ni una sola de tus tareas.</p>
<h3 style="text-align: justify">2. ESTO ES IMPOSIBLE</h3>
<p style="text-align: justify">&#8220;<em>Sí, eso de la Técnica Pomodoro suena muy bien pero, en mi puesto de trabajo, es IMPOSIBLE de aplicar. ¿25 minutos sin coger el teléfono? No funcionaría</em>&#8220;. Frases como la anterior son habituales cuando hablas con gente sobre la Técnica Pomodoro. Aunque hay entornos laborales verdaderamente hostiles al empleo de la técnica como, por ejemplo, el de una recepcionista&#8230; o el de un tornero fresador, la Técnica Pomodoro puede aplicarse  (bien) en muchos más entornos de los que la gente cree.</p>
<p style="text-align: justify">¿Te resulta imposible no coger el teléfono durante 25 minutos? Pues no lo hagas. Cógelo todas las veces que te haga falta, aunque claro&#8230; eso significará que romperás tus <em>pomodoros </em>y que <strong>tendrás que comenzar de nuevo</strong> ¿y? No pasa nada. Sigues con tu lista de tareas y vas marcando las que concluyas, los pomodoros que completes y las interrupciones que sufras.</p>
<p style="text-align: justify">
<h3>3. LA  TÉCNICA POMODORO ES <span style="text-decoration: underline">MUY</span> DURA</h3>
<p style="text-align: justify">Uno de los mitos de la Técnica Pomodoro es que hace que la gente trabaje menos y se tome más descansos que un funcionario público. Craso error.</p>
<p style="text-align: justify">&#8220;<em>Espera, espera, espera&#8230; pero, si rompo mis pomodoros, entonces&#8230; no puedo tomarme los cinco minutitos de descanso ¿no?</em>&#8221; Pues no, amiguete. Quiero decir, puedes tomarte cinco o cincuenta pero, no estarías cumpliendo la Técnica Pomodoro.</p>
<p style="text-align: justify">Seguir la Técnica Pomodoro es MUY duro y, creedme, si conseguís concluir un pomodoro, necesitaréis esos cinco minutos de descanso, para ir al baño, para contestar algún correo o tomaros una café.</p>
<p style="text-align: justify">Cuando llevas 23 minutos dándolo todo, te quedan 2 minutos para ganarte tu descanso y te llega alguien con una pregunta estúpida, en seguida comprendes el concepto de &#8220;<em>protege tu pomodoro</em>&#8220;. Ya te digo si lo proteges ¡con uñas y dientes!.</p>
<p style="text-align: justify">Si consigo concluir cuatro pomodoros y me tomo ese descanso de quince a veinticinco minutos, creedme, lo hago sin ningún tipo de remordimiento. Sé que estoy siendo rentable, muy rentable para la empresa.</p>
<p style="text-align: justify">Seguir (bien) la Técnica Pomodoro es tan duro y requiere tal disciplina que <strong>hay días que directamente no la aplico y me la salto</strong>. Cuando trabajo haciendo <em>pomodoros</em> suelo acabar tremendamente agotado pero, también, tremendamente satisfecho porque sé que he dado todo lo que tengo dentro, que me he vaciado y que no he perdido el tiempo.</p>
<p style="text-align: justify">&#8230;</p>
<p style="text-align: justify">Me dejo cosas en el tintero, pero no quería que este artículo fuera uno de mis <em>ladrillos </em>interminables. También estoy preparando un artículo sobre <strong>Técnica Pomodoro Extrema</strong> para ayudar a llegar al límite a aquellos de vosotros que la practiquéis. Incluso la gente de <a href="http://www.okurispaces.com/" target="_blank">Okuri Spaces</a> me han comentado la posibilidad de dar alguna charla o curso en sus instalaciones sobre la Técnica Pomodoro por lo que, si estáis interesados en saber más, por favor hacédmelo saber a través de los comentarios o del <a href="http://sixservix.com/blog/david/about/" target="_blank">formulario de contacto</a> de esta web. Muchas Gracias.</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/07/20/tecnica-pomodoro-extrema/' rel='bookmark' title='Permanent Link: Técnica Pomodoro Extrema'>Técnica Pomodoro Extrema</a> <small>Como utilizar la Técnica Pomodoro para llegar donde nadie ha...</small></li>
<li><a href='http://sixservix.com/blog/david/2010/02/03/tecnica-pomodoro-record-sheet/' rel='bookmark' title='Permanent Link: Técnica Pomodoro: Record Sheet'>Técnica Pomodoro: Record Sheet</a> <small>Cada vez somos más los que seguimos la Técnica Pomodoro...</small></li>
<li><a href='http://sixservix.com/blog/david/2009/11/26/la-tecnica-pomodoro/' rel='bookmark' title='Permanent Link: La Técnica Pomodoro'>La Técnica Pomodoro</a> <small>Voy a intentar explicar de una forma divertida y amena...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/07/13/no-sabes-nada-de-la-tecnica-pomodoro/feed/</wfw:commentRss>
		<slash:comments>18</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>Como aprender a programar C++ en 21 días</title>
		<link>http://sixservix.com/blog/david/2010/05/07/aprender-c-en-21-dias/</link>
		<comments>http://sixservix.com/blog/david/2010/05/07/aprender-c-en-21-dias/#comments</comments>
		<pubDate>Fri, 07 May 2010 04:50:59 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[humor]]></category>
		<category><![CDATA[abstrusegoose]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=2919</guid>
		<description><![CDATA[El único método garantizado para aprender a programar C++ en 21 días...]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify">El único método garantizado para <strong>aprender a programar C++</strong> en 21 días&#8230;</p>
<p style="text-align: center">
<p><img class="size-full wp-image-2921 alignnone" style="border: 0pt none" src="http://sixservix.com/blog/david/files/2010/05/aprender_c.jpg" alt="aprender_c" width="600" height="515" /></p>
<p style="text-align: justify">RT @<a href="http://abstrusegoose.com/249" target="_blank">abstrusegoose</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/05/07/aprender-c-en-21-dias/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Certificándome como Scrum Master</title>
		<link>http://sixservix.com/blog/david/2010/04/27/scrum-master/</link>
		<comments>http://sixservix.com/blog/david/2010/04/27/scrum-master/#comments</comments>
		<pubDate>Tue, 27 Apr 2010 04:50:59 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[agile]]></category>
		<category><![CDATA[david]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[Alan Cyment]]></category>
		<category><![CDATA[Ariel Ber]]></category>
		<category><![CDATA[csm]]></category>
		<category><![CDATA[pajarraco]]></category>
		<category><![CDATA[scrum]]></category>
		<category><![CDATA[scrum master]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=2809</guid>
		<description><![CDATA[Me he certificado como Scrum Master ¿Tiene eso algo que ver con He-Man y Skeletor? ¿Para que sirve la certificación? Te lo explico todo en este artículo...]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-full wp-image-2811" style="border: 0pt none;margin-right: 10px" src="http://sixservix.com/blog/david/files/2010/04/scrum_board_pixel.jpg" alt="scrum_board_pixel" width="250" height="161" />La semana pasada, asistí durante dos días a un curso de certificación como<strong> Scrum Master</strong><span> </span>pagado por mi empresa (<em>kudos<span> </span></em>para<span> </span><a href="http://sixservix.com/es/historia.php" target="_blank">sixservix</a>) e impartido por<span> </span><a href="http://www.cyment.com/alan-cyment/" target="_blank">Alan Cyment</a><span> </span>y <a href="http://arielber.com/about/" target="_blank">Ariel Ber</a>.</p>
<p style="text-align: justify">Existen muchas dudas sobre el contenido y valía de esta certificación. En algunos casos, porque hay gente que no sabe (o no sabe BIEN) qué es eso de <a href="http://www.proyectosagiles.org/que-es-scrum" target="_blank">scrum</a>; y, en otros casos, porque los que sí conocen<span> </span><strong>scrum<span> </span></strong>no entienden qué valor puede aportar una certificación sobre la materia.</p>
<p style="text-align: justify">No voy a escribir otro artículo sobre qué es<span> </span><strong>scrum -</strong>hay mucha y<span> </span><a href="http://scrum.es/scrum/explicar-scrum-en-diez-minutos/" target="_blank">buena literatura sobre la materia</a>- pero si os voy a contar mi opinión y sensaciones sobre el curso en concreto.</p>
<p style="text-align: justify">La primera pregunta que debo responder es: <strong>¿Mereció la pena asistir al curso?</strong><span> </span><strong>Sí, sin duda</strong>.<span> </span><span style="text-decoration: underline">Es uno de los mejores cursos a los que he asistido</span>. No sólo por el contenido del mismo, sino por la forma de estructurar y enfocar la materia que practicaron los dos profesores.</p>
<p style="text-align: justify">Durante dos días,<span> </span><strong>no vimos ni una sola diapositiva ni encendimos un ordenador</strong>. El planteamiento, desde luego, fue algo refrescante para aquellos que provenimos del mundo de la informática. A través de actividades y juegos como &#8220;El hipnotizador Colombiano&#8221; o &#8220;El vampiro de Hamburgo&#8221;, aprendí aspectos del comportamiento humano sobre los que asienta<span> </span><strong>scrum<span> </span></strong>su pragmatismo.</p>
<p style="text-align: justify">Que había que demostrar la resolución de sistemas complejos mediante empirismo, pues nos ponían a dibujar triángulos isósceles trotando por un plano que era la clase y donde los vértices éramos nosotros mismos. Que había que poner en práctica<span> </span><strong>scrum<span> </span></strong>y ver cómo lo practicábamos (mal), pues a jugar al famoso &#8220;<a href="http://sixservix.com/blog/david/files/2010/04/pajarraco.jpg" target="_blank">Juego del Pajarraco</a>&#8220;, inventando por Alan.</p>
<p style="text-align: justify">Creedme, ver a 20 adultos tirados en el suelo, construyendo un<span> </span><em>pajarraco</em><span> </span>con piezas de Lego, estresados ante la presión del tiempo y un montón de requisitos cambiantes, es algo digno de ver.<span> </span><strong>Y</strong><span> </span><strong>muy muy pedagógico</strong>.</p>
<p style="text-align: justify">Ariel y Alan no se limitan a dictarte las reglas de<span> </span><strong>scrum<span> </span></strong>que cualquiera puede encontrar en Internet<em>.<span> </span></em><strong>No te enseñan scrum, te hacen VIVIR scrum</strong>.</p>
<p style="text-align: justify">
<div id="attachment_2832" class="wp-caption alignright" style="width: 176px"><img class="size-full wp-image-2832  " src="http://sixservix.com/blog/david/files/2010/04/logo-certified-scrum-master-seal.jpg" alt="El sello de Certified Scrum Master. Para molar :)" width="166" height="169" /><p class="wp-caption-text">El sello de Certified Scrum Master. Para molar.</p></div>
<p style="text-align: justify">Por otro lado,<span> </span><strong>asistir al curso te da derecho a hacer el examen de Scrum Master</strong> certificado por la<span> </span><a href="http://www.scrumalliance.org/" target="_blank">Scrum Alliance</a> (CSM). Lo que<span> </span><span style="text-decoration: underline">en la práctica supone certificarte automáticamente, puesto que el examen sólo es una mera prueba de auto-evaluación: no se puede suspender</span>.</p>
<p style="text-align: justify">Realmente, la certificación como<span> </span><strong>Scrum Master</strong><span> </span>significa que asististe durante dos días a un curso impartido por un pedagogo reconocido por la<span> </span><strong>Scrum Alliance</strong>. Ni más ni menos. ¡Ah, sí! Y que puedes adornar tu<span> </span><em>blog<span> </span></em>y tu<span> </span><em>curriculum<span> </span></em>con este logo tan chulo de aquí a la derecha. Es naranja, tiene círculos y una cresta&#8230; y<span> </span><a href="http://mx.answers.yahoo.com/question/index?qid=20090106121039AAmg9tn" target="_blank">se parece sospechosamente a un logro de videojuego de la 360</a>.</p>
<p style="text-align: justify">Eso si, tener el CSM es uno de los requisitos que se exigen para convertirte en<em><span> </span><a href="http://www.scrumalliance.org/CSP" target="_blank">Certified Scrum Professional</a><span> </span></em>o CSP, el siguiente paso que debes dar si quieres dedicarte a enseñar<span> </span><strong>scrum<span> </span></strong>al resto del mundo con el respaldo de la<span> </span><strong>Scrum Alliance</strong>.</p>
<p style="text-align: justify">Como conclusión: sí, recomiendo el curso de<span> </span><em>Certified Scrum Master</em>, pero <strong>lo que de verdad os recomiendo es el curso de<span> </span><em>Certified Scrum Master</em><span> </span></strong><strong>impartido por Alan y Ariel </strong>que es el que yo viví y disfruté. En mi caso, ellos y la fantástica dinámica de grupo creada junto a todos mis compañeros fueron los que hicieron especiales y mágicos esos dos días.</p>
<h3 style="text-align: justify">¿EPÍLOGO&#8230; O PRÓLOGO?</h3>
<p style="text-align: justify">El lunes llegué al trabajo y comencé a explicar<span> </span><strong>scrum<span> </span></strong>de una manera natural a un equipo que no lo conocía. No sólo tenía los conocimientos, los había interiorizado. Conceptualizábamos, priorizábamos y planificábamos nuestro primer &#8216;proyecto&#8217;<span> </span><strong>scrum</strong>: un curso de formación para nuevos usuarios de nuestra aplicación de almacenes.</p>
<p style="text-align: justify">Por supuesto, tuve que afrontar las preguntas más o menos inquisitorias de los más escépticos con el marco de trabajo. Algunas eran de libro. Otras, sin embargo, las pude responder improvisando con las técnicas y conocimientos que me habían enseñado la semana pasada. Me sentí bien. Me sentí seguro. No era un mero robot que repetia las cuatro normas del marco de trabajo. Era un <em>Scrum Master</em> (novato) que utilizaba la visión y los valores de <strong>scrum </strong>para responder a las dudas y preguntas del equipo. Alan y Ariel me habían preparado bien.</p>
<p style="text-align: justify">No debí hacerlo del todo mal porque un compañero me felicitó por la charla durante la hora de la comida &#8220;<em>Me gusta<span> </span></em><em>scrum</em><em>. Encaja. Parece que tiene respuestas para todo</em>&#8220;.</p>
<p style="text-align: justify">No estoy seguro de que <strong>scrum<span> </span></strong>tenga respuestas para todo, pero sí sé que quiero ir contestando las preguntas poco a poco. Como mis profesores dicen:<span> </span><strong>el curso no es más que el primer paso en un largo, larguísimo camino</strong>.</p>
<p style="text-align: justify">
<p style="text-align: center"><img class="aligncenter" style="border-width: 0px;margin-left: auto;margin-right: auto" src="http://sixservix.com/blog/david/files/2010/04/mi_primer_taskboard.jpg" alt="mi_primer_taskboard" width="600" height="450" /></p>
<p style="text-align: center"><em>Nuestro primer taskboard</em></p>
<p style="text-align: justify">
]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/04/27/scrum-master/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Tagging: Categorías vs. Etiquetas</title>
		<link>http://sixservix.com/blog/david/2010/03/03/tagging/</link>
		<comments>http://sixservix.com/blog/david/2010/03/03/tagging/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 05:50:31 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[categorias]]></category>
		<category><![CDATA[etiquetas]]></category>
		<category><![CDATA[indexación]]></category>
		<category><![CDATA[tags]]></category>
		<category><![CDATA[web 2.0]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=1726</guid>
		<description><![CDATA[Tradicionalmente, los informáticos hemos categorizado la información para estructurarla y facilitar el trabajo con ella. Sin embargo, parece que el trabajo con categorías ha quedado desfasado tras la irrupción del mundo web 2.0. Han llegado las tags, las etiquetas y, con éstas, toda una revolución de la forma en la que gestionamos nuestra información. ¿Han [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-full wp-image-2177" src="http://sixservix.com/blog/david/files/2010/02/etiqueta.jpg" alt="etiqueta" width="194" height="315" />Tradicionalmente, los informáticos hemos <em>categorizado </em>la información para estructurarla y facilitar el trabajo con ella. Sin embargo, parece que el trabajo con <strong>categorías </strong>ha quedado desfasado tras la irrupción del mundo <em>web 2.0.</em> Han llegado las <em>tags</em>, las <strong>etiquetas </strong>y, con éstas, toda una revolución de la forma en la que gestionamos nuestra información. ¿Han muerto las categorías? ¿Qué son exactamente eso de las <strong><em>tags</em></strong>? Si debes diseñar una aplicación, es importante que conozcas las diferencias entre unas y otras.</p>
<p style="text-align: justify">Una etiqueta o <span style="text-decoration: underline"><em>tag </em>es un término <strong>no jerárquico</strong> asociado a una porción de información determinada</span>, que funciona como un metadato que contribuye a la descripción de la información en sí y permite que dicha información sea recuperada en búsquedas posteriores.</p>
<p style="text-align: justify">Lo importante, lo único realmente importante del &#8216;<em>frasón</em>&#8216; anterior y <strong>lo que distingue una categoría de una etiqueta es que esta última no es jerárquica</strong>.</p>
<p style="text-align: justify">Mientras que es posible definir una categoría como un elemento estructurado que permite facilitar la navegación por la misma,<strong> una etiqueta puede usarse libremente sin jerarquía alguna</strong>. Así, por ejemplo, cuando visitamos un artículo perteneciente a la categoría &#8216;deportes&#8217; podemos navegar por las categorías inferiores &#8216;<em>fútbol</em>&#8216; o &#8216;<em>ciclismo</em>&#8216;; o navegar por la categoría superior &#8216;<em>hobbies</em>&#8216;. En cambio, si utilizamos <em>tags</em>, el artículo tendrá un conjunto de etiquetas, como &#8216;<em>fútbol</em>&#8216; &#8216;<em>Atlético de Madrid</em>&#8216; o &#8216;<em>Cristiano Ronaldo</em>&#8216;, <span style="text-decoration: underline">sin ninguna relación entre sí</span> más que la propia asociación con dicho artículo.</p>
<h3 style="text-align: justify">VENTAJAS Y DESVENTAJAS DEL USO DE CATEGORÍAS Y ETIQUETAS</h3>
<p style="text-align: justify">La principal ventaja de las <strong>categorías </strong>es que <strong>permiten estructurar la información</strong> y, si se usan adecuadamente, no tienen un número muy elevado. Esto permite que las búsquedas de información mediante la navegación por las categorías sea cómoda y sencilla.</p>
<p style="text-align: justify">El inconveniente de las categorías viene precisamente de su <strong>número limitado</strong> y su <strong>rigidez</strong>. Son creadas por administradores y es posible que no cumplan todas las necesidades de categorización de los usuarios o que estos usuarios no sepan cómo utilizarlas correctamente.</p>
<p style="text-align: justify">Las etiquetas tienen la ventaja de que <strong>no están predefinidas</strong>. El propio usuario las crea y las usa. No existe el problema de elegir la categoría apropiada para una información; se crean y se asocian las etiquetas  que mejor representen el contenido.</p>
<p style="text-align: justify">El problema de las etiquetas es que la creación y el uso de las mismas implica la aparición de <strong>homónimos</strong> (etiquetas que se usan con diferentes significados) y <strong>sinónimos </strong>(múltiples etiquetas con el mismo significado), lo que puede dificultar la búsqueda de la información etiquetada.</p>
<h3 style="text-align: justify">CUÁNDO UTILIZAR CATEGORÍAS Y CUÁNDO UTILIZAR ETIQUETAS</h3>
<p style="text-align: justify">Una vez comprendidos los pros y contras de categorías y etiquetas, podemos decidir cuándo es adecuado utilizar categorías, <em>tags </em>o ambos conceptos para catalogar nuestra información. Aunque parece que se pueden extraer dos conceptos claros:</p>
<ul>
<li>Si la creación de información depende de <strong>procesos propios</strong> de nuestra aplicación y dicha información puede ser <strong>validada y catalogada</strong> de forma más o menos automática, entonces el uso de categorías parece lo más adecuado.</li>
<li>Si la información tiene<strong> múltiples orígenes</strong> con <strong>criterios de creación heterogéneos</strong>, parece más adecuado el uso de etiquetas.</li>
</ul>
<p style="text-align: justify">El uso de <em>tags <span style="text-decoration: underline">se </span></em><span style="text-decoration: underline">ha extendido exponencialmente desde el comienzo de la <a href="http://en.wikipedia.org/wiki/Web_2.0" target="_blank">web 2.0</a> y la <a href="http://en.wikipedia.org/wiki/Semantic_Web" target="_blank">web semántica</a></span>, debido a que la información es creada de forma directa por los propios usuarios de las aplicaciones, en vez de por los administradores de las mismas. Si tienes un sitio como <strong>YouTube</strong>, parece que no tiene mucho sentido que crees unas categorías predefinidas para los vídeos, seguro que tus usuarios acabarán sorprendiéndote.</p>
<p style="text-align: center"><img class="aligncenter size-full wp-image-2195" src="http://sixservix.com/blog/david/files/2010/02/tags.jpg" alt="tags" width="399" height="316" /></p>
<p style="text-align: justify">Sin embargo, <strong>sería absurdo que limitáramos el uso de las <em>tags </em>o etiquetas</strong> a las aplicaciones de web 2.0. Se pueden utilizar perfectamente en cualquier tipo de aplicaciones informáticas. En mi caso, por ejemplo, en <strong>algo &#8217;supuestamente&#8217; tan alejado como la gestión de pedidos de <a href="http://sixservix.com/es/storetto.php" target="_blank">STORETTO</a></strong>.</p>
<p style="text-align: justify">Al enfrentarse a los pedidos de mercancía por parte de clientes, los usuarios de la aplicación se han encontrado con que <strong>la categorización de las salidas (simples, a punto de entrega, recogida, devolución, etc.) y los atributos de las mismas no podrían cubrir la infinita casuística</strong> que supone la distribución de bebidas y alimentación. Así, fue natural que solicitaran el uso de etiquetas para los pedidos&#8230; aún cuando ni siquiera conocían el concepto de <em>tagging</em>.</p>
<p style="text-align: justify">Ahora, los usuarios de <strong>storetto </strong>pueden trabajar con pedidos de tipo simple o a punto de entrega y varios más (cada uno con su propia y especifica lógica de negocio) Además, pueden etiquetarlos con términos de lo más pintoresco: &#8216;<em>mercancía peligrosa</em>&#8216;, &#8216;<em>para la ruta de Xirivella</em>&#8216;, &#8216;<em>miércoles</em>&#8216;, &#8216;<em>trailer</em>&#8216;, &#8216;<em>Carlos</em>&#8216; o &#8216;<em>pagado</em>&#8216;, por poner algunos ejemplos.</p>
<p style="text-align: justify">No es que seamos unos pioneros, ya se puede ver el uso de <em>tagging</em> en los ámbitos más diversos, desde la <a href="http://windows.microsoft.com/en-US/windows-vista/Tag-pictures-so-theyre-easier-to-find" target="_blank">gestión de ficheros de Güindous</a>, los <a href="http://support.mozilla.com/en-US/kb/Bookmark%20Tags" target="_blank">marcadores de Firefox</a> o en aplicaciones web tan conocidas como <a href="http://sixservix.com/es/jira.php" target="_blank">JIRA</a>.</p>
<p style="text-align: justify">Los desarrolladores tendemos a <strong>autoformarnos en tecnología pura y dura</strong>. Como mucho, invertimos tiempo en aprender y memorizar como mandriles <a href="http://es.wikipedia.org/wiki/Patr%C3%B3n_de_dise%C3%B1o" target="_blank">patrones de diseño</a>, sin darnos cuenta de que repetimos  muchos de estos patrones sin plantearnos si hay otras opciones más optimas. Espero que este artículo haya abierto los ojos a más de un diseñador de aplicaciones, como yo los abrí en su momento. Sin caer en la tentación de meter etiquetas con calzador en cualquier rincón de nuestra aplicación, hay que considerar el <em>tagging</em> o etiquetado como un recurso de diseño que no debemos despreciar.</p>
<p style="text-align: justify">
<h3 style="text-align: justify"><strong>BIBLIOGRAFÍA Y ENLACES</strong></h3>
<ul>
<li><span style="color: #008000"><strong><a href="http://en.wikipedia.org/wiki/Tag_%28metadata%29" target="_blank">Tag como metadato (Wikipedia)</a></strong></span></li>
<li><span style="color: #008000"><strong><a href="http://en.wikipedia.org/wiki/Knowledge_tag" target="_blank">Knowledge Tag (Wikipedia)</a></strong></span></li>
<li><span style="color: #008000"><strong><a href="http://haacked.com/archive/2006/09/27/Categories_vs_Tags.aspx" target="_blank">Categories vs. Tags (Haacked.com)</a></strong></span></li>
<li><span style="color: #008000"><strong><a href="http://www.duncanmackenzie.net/blog/categories-vs-tags-in-blogs-and-blog-editors/" target="_blank">Categories vs. Tags in blogs (Duncan McKenzie)</a></strong></span></li>
<li><span style="color: #008000"><strong><a href="http://www.usabilitypost.com/2008/10/17/categories-vs-tags/" target="_blank">Categories vs. Tags (Usabilitypost.com)</a></strong></span></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/03/03/tagging/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Bonitruco: averigua desde donde se configura Oracle</title>
		<link>http://sixservix.com/blog/david/2010/02/23/tnsnames/</link>
		<comments>http://sixservix.com/blog/david/2010/02/23/tnsnames/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 09:24:25 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[sqlnet]]></category>
		<category><![CDATA[sqlnet.ora]]></category>
		<category><![CDATA[tnsnames]]></category>
		<category><![CDATA[tnsnames.ora]]></category>
		<category><![CDATA[tnsping]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=2122</guid>
		<description><![CDATA[Uno de los problemas más habituales a la hora de trabajar con la base de datos Oracle y todos sus productos asociados es averiguar donde está el fichero TNSNAMES.ORA que configura los alias de las cadenas de conexión a distintas bases de datos. O, mas exactamente cuál -de los trescientos que se puede acabar teniendo [...]


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-2125" src="http://sixservix.com/blog/david/files/2010/02/tnsnames.jpg" alt="tnsnames" width="216" height="216" />Uno de los problemas más habituales a la hora de trabajar con la base de datos <strong>Oracle</strong> y todos sus productos asociados es averiguar donde está el fichero <a href="http://www.orafaq.com/wiki/Tnsnames.ora" target="_blank">TNSNAMES.ORA</a> que <strong>configura los alias de las cadenas de conexión a distintas bases de datos</strong>. O, mas exactamente cuál -de los trescientos que se puede acabar teniendo en una máquina- es el fichero <em>tnsnames.ora</em> que configura realmente la conexión.</p>
<p style="text-align: justify">Afortunadamente, <span style="text-decoration: underline">cuando se trabaja con java no se utilizan estos ficheros de configuración externos</span>. Se pueden guardar y utilizar las adenas de conexión y usarlas directamente con el <em>driver </em>JDBC de tipo 4 de <strong>Oracle</strong>, pero  siguen siendo necesarios para usar cualquier cliente o programa que utilice el <em>driver</em> nativo de la base de datos como el <a href="http://www.allroundautomations.com/plsqldev.html" target="_blank">PL/SQL Developer</a> o el <a href="http://www.toadsoft.com/toad_oracle.htm" target="_blank">Toad</a>.</p>
<p style="text-align: justify">La <strong>teoría </strong>dice que la variable de entorno <em>TNS_ADMIN</em> es la que configura la ruta donde se encuentra el fichero de configuración <em>tnsnames.ora</em>, pero <a href="http://www.dba-oracle.com/t_windows_tnsnames.ora_file_location.htm" target="_blank">la cosa se empieza a complicar</a> cuando también se involucra a la variable de entorno <em>PATH. </em></p>
<p style="text-align: justify">Cualquier instalación de un producto de <strong>Oracle </strong>-desde Weblogic a Discoverer- suele manipular la variable de entorno <em>PATH</em>, lo que puede provocar, desde <strong>el sorpresivo cambio de la versión de JDK de java que se esta utilizando</strong>&#8230; hasta el cambio de <em>tnsnames.ora</em> que configura el acceso a base de datos Oracle del sistema.</p>
<p style="text-align: justify">Para acabar de rematar la faena, Oracle utiliza una <a href="http://www.databasejournal.com/features/oracle/article.php/3108301/Connecting-with-Oracle-Finding-and-Setting-a-Configuration-File-Location.htm" target="_blank">búsqueda jerárquica de ficheros de configuración</a> y, además, esta jerarquía es <strong>distinta según el sistema operativo utilizado</strong>. Hasta puede llegar a utilizar configuración guardada en otra fichero de configuración: <em>sqlnet.ora</em>, lo que puede volver loco al programador mas duro.</p>
<p style="text-align: justify">Hay un truco para solucionar este problema y averiguar el fichero que configura las conexiones a Oracle: el comando <em>tnsping</em>.</p>
<p style="text-align: justify">El comando <em>tnsping </em>sirve, originalmente, para hacer un <em>ping</em> que compruebe la conexión a una base de datos remota mediante la siguiente sintaxis:</p>
<pre style="text-align: justify"><em>tnsping</em> alias_de_base_de_datos</pre>
<p style="text-align: justify">
<p style="text-align: justify">Pero, además, <strong><em>tnsping </em>indica la ruta física del fichero de configuración</strong> y la propia instalación de Oracle hace que este disponible en el <em>path </em>del sistema, así, se puede utilizar para averiguar donde esta el fichero de configuración de las cadenas de conexión de nuestro sistema, haciendo ping a una base de datos existente o ficticia:</p>
<p style="text-align: center"><img class="size-full wp-image-2141 aligncenter" src="http://sixservix.com/blog/david/files/2010/02/tnsping.jpg" alt="tnsping" width="599" height="387" /></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/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/02/23/tnsnames/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Estructura de una Historia de Usuario</title>
		<link>http://sixservix.com/blog/david/2010/02/10/estructura-historia-usuario/</link>
		<comments>http://sixservix.com/blog/david/2010/02/10/estructura-historia-usuario/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 05:50:10 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[agile]]></category>
		<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[historia de usuario]]></category>
		<category><![CDATA[scrum]]></category>
		<category><![CDATA[user story]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=1967</guid>
		<description><![CDATA[

ID: Identificador de la historia de usuario
TÍTULO: Título descriptivo de la historia de usuario
DESCRIPCIÓN: Descripción sintetizada de la historia de usuario
ESTIMACIÓN: Estimación del coste de implementación en unidades de desarrollo (estas unidades representarán el tiempo teórico de desarrollo/hombre que se estipule al comienzo del proyecto)
PRIORIDAD: Prioridad en la implementación de la historia de usuario respecto [...]


Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/02/08/historias-de-usuario-casos-de-uso/' rel='bookmark' title='Permanent Link: Historias de Usuario vs. Casos de Uso'>Historias de Usuario vs. Casos de Uso</a> <small>Escribiendo documentación sobre metodologías ágiles en general y &#8216;buenas prácticas&#8217;...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="aligncenter size-full wp-image-1985" src="http://sixservix.com/blog/david/files/2010/02/historias_usuario.jpg" alt="historias_usuario" width="569" height="416" /></p>
<ul style="text-align: justify">
<li><strong>ID:</strong> Identificador de la historia de usuario</li>
<li><strong>TÍTULO:</strong> Título descriptivo de la historia de usuario</li>
<li><strong>DESCRIPCIÓN:</strong> Descripción sintetizada de la historia de usuario</li>
<li><strong>ESTIMACIÓN:</strong> Estimación del coste de implementación en unidades de desarrollo (estas unidades representarán el tiempo teórico de desarrollo/hombre que se estipule al comienzo del proyecto)</li>
<li><strong>PRIORIDAD:</strong> Prioridad en la implementación de la historia de usuario respecto al resto de las historias de usuario. A mayor número, mayor prioridad. Otra aproximación a la priorización de tareas se hace a través del <a href="http://en.wikipedia.org/wiki/MoSCoW_Method">método MoSCoW</a>:
<ul>
<li><em>M – Must</em>, se debe completar este requerimiento para finalizar el proyecto</li>
<li><em>S – Should</em>, se debe completar este proyecto por todos los medios, pero el éxito del proyecto no depende de él.</li>
<li><em>C – Could</em>, se debería completar este requerimiento si su implementación no afecta a la consecución de los objetivos principales del proyecto.</li>
<li><em>W – Would</em>, se puede completar este requerimiento si sobra tiempo de desarrollo (o en futuras versiones del mismo)</li>
</ul>
</li>
<li><strong>DEPENDENCIAS</strong>: Una historia de usuario no debería ser dependiente de otra historia, pero a veces es inevitable. En este apartado se indicarían los IDs de las tareas de las que depende una tarea</li>
</ul>
<p style="text-align: justify">El ciclo de vida de la <strong>tarjeta</strong> se compone de tres fases, conocidas como “Las 3 C” por sus iniciales en inglés (<em>Card, Conversation, Confirmation</em>):</p>
<ul style="text-align: justify">
<li><strong>TARJETA</strong> (<em>Card</em>), la creación de la tarjeta en sí, con la estructura definida anteriormente y que sirve para determinar QUÉ se debe hacer y cómo planificarlo.</li>
<li><strong>CONVERSACION</strong> (<em>Conversation</em>), representado por pequeños documentos y anotaciones que sirven para aportar detalles y refinar los datos sobre las características del requerimiento.</li>
<li><strong>CONFIRMACIÓN</strong> (<em>Confirmation</em>), o <strong>pruebas de aceptación</strong>. Pruebas consensuadas entre el cliente y el desarrollador y que el código debe superar para dar como finalizada la implementación del requerimiento.</li>
</ul>
<p style="text-align: justify">
<p style="text-align: justify">(Gracias a <a href="http://devnettips.blogspot.com/2009/03/definiendo-historias-de-usuario-en.html" target="_blank">Vicenç y Jasosa</a> por el ejemplo incluido en la tarjeta)</p>


<p>Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2010/02/08/historias-de-usuario-casos-de-uso/' rel='bookmark' title='Permanent Link: Historias de Usuario vs. Casos de Uso'>Historias de Usuario vs. Casos de Uso</a> <small>Escribiendo documentación sobre metodologías ágiles en general y &#8216;buenas prácticas&#8217;...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2010/02/10/estructura-historia-usuario/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
