JPA 2.1 ¿Cómo implementar un Convertidor de Tipo?

por | Junio 13, 2014

JPA 2.1 viene con muchas mejoras. Una de estas es el Convertidor de Tipo. Permite al desarrollador especificar métodos para convertir atributos “mapeados” entre la base de datos y la representación java.

¿Qué puede ser convertido?

Un Convertidor soporta conversiones de tipo de todas los atributos básicos definidos en las clases de entidad, clases “super” o clases embebidas. La única excepción son los atributos “Id”, atributos de versión, atributos relacionados y atributos anotados con Temporal o Enumarted.

¿Cómo implementar un Convertidor?

Un convertidor debería implementar la interfaz javax.persistence.AttributeConverter<X, Y>, donde X es la clase que representa a la entidad y Y la clase de la representación de base de datos del atributo. Adicionalmente un Convertidor tiene que ser anotada con javax.persistence.Converter.
El siguiente ejemplo muestra como la implementación de un Convertidor puede ser usado para almacenar en la base de datos un objeto java.awt.Color como un String con el formato red|green|blue|alpha. Cuando se lee la entidad desde la base de datos, el String será usado para instanciar un nuevo objeto Color.

package blog.thoughts.on.java.jpa21.converter;

import java.awt.Color;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

@Converter
public class ColorConverter implements AttributeConverter {

 private static final String SEPARATOR = "|";

 /**
  * Convert Color object to a String
  * with format red|green|blue|alpha
  */
 @Override
 public String convertToDatabaseColumn(Color color) {
  StringBuilder sb = new StringBuilder();
  sb.append(color.getRed()).append(SEPARATOR)
     .append(color.getGreen())
     .append(SEPARATOR)
     .append(color.getBlue())
     .append(SEPARATOR)
     .append(color.getAlpha());
  return sb.toString();
 }

 /**
  * Convert a String with format red|green|blue|alpha
  * to a Color object
  */
 @Override
 public Color convertToEntityAttribute(String colorString) {
  String[] rgb = colorString.split(SEPARATOR);
  return new Color(Integer.parseInt(rgb[0]),
      Integer.parseInt(rgb[1]),
      Integer.parseInt(rgb[2]),
      Integer.parseInt(rgb[3]));
 }

}

Como se puede ver la implementación es simple y sencilla. Se necesita implementar un método por cada conversión.

¿Cómo usar un Convertidor?

Hay dos opciones para definir el uso de un Convertidor. La primera es configurar en la anotación @Converter el atributo autoapply=true. En este caso el “provider JPA” usará este convertidor para convertir todas los atributos de entidad del tipo dado.
Si autoapply es configurada como false, necesitas agregar la anotación javax.persistence.Convert a todos los atributos que se quieran(puedan) convertir y especificar la clase Converter. El siguiente fragmento de código muestra un ejemplo de este enfoque:

@Entity
public class RectangleEntity
{

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Integer id;

   @Column
   private Integer x;

   @Column
   private Integer y;

   @Column
   @Convert(converter = ColorConverter.class)
   private Color color;

   ...
}

Esto es todo lo que se necesita para realizar la implementación de un simple Convertidor de Tipo. Para mas características avanzadas de conversiones, revisar la especificación o los Java Doc . Si quieres intentar hacerlo tu mismo, puedes usar Hibernate 4.3.0.Beta4, que es parte de la nueva versión Wildfly 8.0.0.Beta1.

Links

JPA 2.1 Specification
Java Doc javax.persistence

Traducción del artículo original: http://www.thoughts-on-java.org/2013/10/jpa-21-how-to-implement-type-converter.html