{"id":1618,"date":"2014-06-13T12:40:25","date_gmt":"2014-06-13T17:40:25","guid":{"rendered":"http:\/\/alejandroayala.solmedia.ec\/?p=1618"},"modified":"2014-06-13T12:41:46","modified_gmt":"2014-06-13T17:41:46","slug":"jpa-2-1-como-implementar-un-convertidor-de-tipo","status":"publish","type":"post","link":"https:\/\/alejandroayala.solmedia.ec\/?p=1618","title":{"rendered":"JPA 2.1 \u00bfC\u00f3mo implementar un Convertidor de Tipo?"},"content":{"rendered":"<p>JPA 2.1 viene con muchas mejoras. Una de estas es el <strong><em>Convertidor de Tipo<\/em><\/strong>. Permite al desarrollador especificar m\u00e9todos para convertir atributos \u00abmapeados\u00bb entre la base de datos y la representaci\u00f3n java.<\/p>\n<h2>\u00bfQu\u00e9 puede ser convertido?<\/h2>\n<p>Un <em>Convertidor<\/em> soporta conversiones de tipo de todas los atributos b\u00e1sicos definidos en las <strong>clases de entidad<\/strong>, clases \u00absuper\u00bb o clases embebidas. <strong>La \u00fanica excepci\u00f3n<\/strong> son los atributos \u00abId\u00bb, atributos de versi\u00f3n, atributos relacionados y atributos anotados con <em>Temporal<\/em> o <em>Enumarted<\/em>.<\/p>\n<p><!--more--><\/p>\n<h2>\u00bfC\u00f3mo implementar un Convertidor?<\/h2>\n<p>Un convertidor deber\u00eda implementar la interfaz <em><strong>javax.persistence.AttributeConverter&lt;X, Y&gt;<\/strong><\/em>, donde <strong>X<\/strong> es la clase que representa a la entidad y <strong>Y<\/strong> la clase de la representaci\u00f3n de base de datos del atributo. Adicionalmente un <em>Convertidor<\/em> tiene que ser anotada con <em><strong>javax.persistence.Converter<\/strong><\/em>.<br \/>\nEl siguiente ejemplo muestra como la implementaci\u00f3n de un <em>Convertidor<\/em> puede ser usado para almacenar en la base de datos un objeto<em><strong> java.awt.Color<\/strong><\/em> como un <em>String<\/em> con el formato <em>red|green|blue|alpha<\/em>. Cuando se lee la entidad desde la base de datos, el <em>String<\/em> ser\u00e1 usado para instanciar un nuevo objeto <em><strong>Color<\/strong><\/em>.<\/p>\n<p>[java]<br \/>\npackage blog.thoughts.on.java.jpa21.converter;<\/p>\n<p>import java.awt.Color;<\/p>\n<p>import javax.persistence.AttributeConverter;<br \/>\nimport javax.persistence.Converter;<\/p>\n<p>@Converter<br \/>\npublic class ColorConverter implements AttributeConverter {<\/p>\n<p> private static final String SEPARATOR = &quot;|&quot;;<\/p>\n<p> \/**<br \/>\n  * Convert Color object to a String<br \/>\n  * with format red|green|blue|alpha<br \/>\n  *\/<br \/>\n @Override<br \/>\n public String convertToDatabaseColumn(Color color) {<br \/>\n  StringBuilder sb = new StringBuilder();<br \/>\n  sb.append(color.getRed()).append(SEPARATOR)<br \/>\n     .append(color.getGreen())<br \/>\n     .append(SEPARATOR)<br \/>\n     .append(color.getBlue())<br \/>\n     .append(SEPARATOR)<br \/>\n     .append(color.getAlpha());<br \/>\n  return sb.toString();<br \/>\n }<\/p>\n<p> \/**<br \/>\n  * Convert a String with format red|green|blue|alpha<br \/>\n  * to a Color object<br \/>\n  *\/<br \/>\n @Override<br \/>\n public Color convertToEntityAttribute(String colorString) {<br \/>\n  String[] rgb = colorString.split(SEPARATOR);<br \/>\n  return new Color(Integer.parseInt(rgb[0]),<br \/>\n      Integer.parseInt(rgb[1]),<br \/>\n      Integer.parseInt(rgb[2]),<br \/>\n      Integer.parseInt(rgb[3]));<br \/>\n }<\/p>\n<p>}<\/p>\n<p>[\/java]<\/p>\n<p>Como se puede ver la implementaci\u00f3n es simple y sencilla. Se necesita implementar un m\u00e9todo por cada conversi\u00f3n.<\/p>\n<h2>\u00bfC\u00f3mo usar un Convertidor?<\/h2>\n<p>Hay dos opciones para definir el uso de un <em>Convertidor<\/em>. La primera es configurar en la anotaci\u00f3n <em><strong>@Converter<\/strong><\/em> el atributo <strong><em>autoapply=true<\/em><\/strong>. En este caso el \u00ab<em>provider<\/em> <em>JPA<\/em>\u00bb usar\u00e1 este convertidor para convertir todas los atributos de entidad del tipo dado.<br \/>\nSi <em>autoapply<\/em> es configurada como <em><strong>false<\/strong><\/em>, necesitas agregar la anotaci\u00f3n<em><strong> javax.persistence.Convert<\/strong><\/em> a todos los atributos que se quieran(puedan) convertir y especificar la clase <em><strong>Converter<\/strong><\/em>. El siguiente fragmento de c\u00f3digo muestra un ejemplo de este enfoque:<\/p>\n<p>[java]<br \/>\n@Entity<br \/>\npublic class RectangleEntity<br \/>\n{<\/p>\n<p>   @Id<br \/>\n   @GeneratedValue(strategy = GenerationType.IDENTITY)<br \/>\n   private Integer id;<\/p>\n<p>   @Column<br \/>\n   private Integer x;<\/p>\n<p>   @Column<br \/>\n   private Integer y;<\/p>\n<p>   @Column<br \/>\n   @Convert(converter = ColorConverter.class)<br \/>\n   private Color color;<\/p>\n<p>   &#8230;<br \/>\n}<br \/>\n[\/java]<\/p>\n<p>Esto es todo lo que se necesita para realizar la implementaci\u00f3n de un simple <em>Convertidor<\/em> de Tipo. Para mas caracter\u00edsticas avanzadas de conversiones, revisar la especificaci\u00f3n o los <em>Java Doc<\/em> . Si quieres intentar hacerlo tu mismo, puedes usar <em><strong>Hibernate 4.3.0.Beta4<\/strong><\/em>, que es parte de la nueva versi\u00f3n <em><strong>Wildfly 8.0.0.Beta1.<\/strong><\/em><\/p>\n<h3>Links<\/h3>\n<p><a href=\"http:\/\/jcp.org\/en\/jsr\/detail?id=338\" target=\"_blank\">JPA 2.1 Specification<\/a><br \/>\n<a href=\"http:\/\/docs.oracle.com\/javaee\/7\/api\/javax\/persistence\/package-summary.html\" target=\"_blank\"> Java Doc javax.persistence<\/a><\/p>\n<p><strong>Traducci\u00f3n del art\u00edculo original:<\/strong> <a href=\"http:\/\/www.thoughts-on-java.org\/2013\/10\/jpa-21-how-to-implement-type-converter.html\" target=\"_blank\">http:\/\/www.thoughts-on-java.org\/2013\/10\/jpa-21-how-to-implement-type-converter.html<\/a><\/p>\n\n<div class=\"twitter-share\"><a href=\"https:\/\/twitter.com\/intent\/tweet?via=a1ejo_ayala\" class=\"twitter-share-button\" data-size=\"large\">Twittear<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>JPA 2.1 viene con muchas mejoras. Una de estas es el Convertidor de Tipo. Permite al desarrollador especificar m\u00e9todos para convertir atributos \u00abmapeados\u00bb entre la base de datos y la representaci\u00f3n java. \u00bfQu\u00e9 puede ser convertido? Un Convertidor soporta conversiones de tipo de todas los atributos b\u00e1sicos definidos en las clases de entidad, clases \u00absuper\u00bb\u2026 <span class=\"read-more\"><a href=\"https:\/\/alejandroayala.solmedia.ec\/?p=1618\">Leer m\u00e1s &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":690,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[4],"tags":[445,173,506,203],"_links":{"self":[{"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/posts\/1618"}],"collection":[{"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1618"}],"version-history":[{"count":3,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/posts\/1618\/revisions"}],"predecessor-version":[{"id":1621,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/posts\/1618\/revisions\/1621"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/media\/690"}],"wp:attachment":[{"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1618"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1618"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1618"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}