martes, 19 de mayo de 2009

Eclipse: Detail formatters

Todos los que nos hemos peleado con el depurador de Eclipse (sin el que no sería nadie) nos habremos fijado en la poca información que se muestra en la vista Variables a primera instancia. Por ejemplo, si tenemos una clase Usuario como esta:

Y estamos depurando el siguiente "programa":

La información que nos muestra la vista (si no entramos a desglosar la variable que nos interesa, y no se ha implementado el método toString) nos dice bastante poco.


Para evitar esto, Eclipse nos permite usar una expresión alternativa al toString. Para ello, en tiempo de depuración, pulsamos con el botón derecho sobre la variable que nos interese y seleccionamos New Detail Formater


El editor nos permitirá escribir expresiones, haciendo uso de los métodos y atributos de la clase seleccionada (Usuario), y ofreciendo la posibilidad de autocompletar el texto al escribir. Si escribimos algo como lo siguiente:


Ahora la información mostrada en la vista Variables nos dice mucho más.

Si además queremos que se muestre en la columna Value, accedemos a Window - Preferences - Java - Debug - Detail Formatters y seleccionamos la casilla "As the label for variables ..."


Con lo que ahora la vista quedaría así:

miércoles, 13 de mayo de 2009

Hibernate: @Embeddable

Supongamos que estamos ante la siguiente situación: varias clases de nuestro modelo comparten ciertos atributos, y por las razones que sean, no es posible/conveniente plantearlo con herencia. Por ejemplo, varias clases almacenan un peso y una altura. Podríamos tener una clase Medidas, que centralizara estos campos, e indicar que será "embebida":


package es.gmr.pruebas;

import javax.persistence.Column;
import javax.persistence.Embeddable;

@Embeddable
public class Medidas {
   @Column(name="PESO")
   Integer peso;
   @Column(name="ALTURA")
    Integer altura;

    ...

}


Ahora, cada clase que necesite estos campos, sólo tendrá que añadir una instancia de Medidas y ya tendrá incluida las anotaciones para peso y altura como si fueran atributos propios.

¿Pero qué pasa si para una determinada clase, las columnas de la tabla correspondiente en base de datos no se llaman PESO y ALTURA?. ¿O si una clase en concreto necesita dos instancias de Medidas? En esos casos podríamos sobrescribir el mapeo, con la anotación @AttributeOverrides. Un ejemplo:


package es.gmr.pruebas;

import javax.persistence.*;

@Entity
@Table(name = "MY_CLASE")
public class MyClase {
    // Usará los valores dados por defecto en el mapeo
    Medidas unaMedida;

    @Embedded
    @AttributeOverrides( {
       @AttributeOverride(name="peso", column =
          @Column(name="OTRO_PESO") ),
       @AttributeOverride(name="altura", column =
          @Column(name="OTRA_ALTURA") )
    } )
    IntegerMedidas otraMedida;

    ...
}