Datanucleus – Primary Key compuesto por varias propiedades

agosto 8, 2012

En el diseño de bases de datos relacionales, se llama clave primaria a un campo o a una combinación de campos que identifica de forma única a cada fila de una tabla. No pueden haber dos filas en una tabla que tengan la misma clave primaria.
Un ejemplos de claves primarias es el ISBN (asociado a un libro).

Supongamos que tenemos una entidad Usuario que es identificada por 2 propiedades: id e idJuzgado. Para especificar la llave compuesta en Datanucleus lo haríamos de la siguiente manera:

@PersistenceCapable(objectIdClass=Usuario.ComposedIdKey.class)
public class Usuario {

public static class ComposedIdKey implements Serializable
{
    public Integer id;
    public String idJuzgado;

    public ComposedIdKey ()
    {
    }

    /**
     * Constructor accepting same input as generated by toString().
     */
    public ComposedIdKey(String value)
    {
        StringTokenizer token = new StringTokenizer (value, "::");
        token.nextToken();               // className
        this.id = Integer.parseInt(token.nextToken()); // field1
        this.idJuzgado = token.nextToken(); // field2
    }

    public boolean equals(Object obj)
    {
        if (obj == this)
        {
            return true;
        }
        if (!(obj instanceof ComposedIdKey))
        {
            return false;
        }
        ComposedIdKey c = (ComposedIdKey)obj;
        return id.equals(c.id) && idJuzgado.equals(c.idJuzgado);
    }

    public int hashCode ()
    {
        return this.id.hashCode() ^ this.idJuzgado.hashCode();
    }

    public String toString ()
    {
        // Give output expected by String constructor
        return this.getClass().getName() + "::"  + this.id + "::" + this.idJuzgado;
    }
}

@PrimaryKey
Integer id;
@PrimaryKey
String idJuzgado;
String nombre;
String apellidoPaterno;
String apellidoMaterno;

public Usuario() {
}

public Integer getId() {return id;}
public void setId(Integer id) {this.id = id;}
public String getNombre() {return nombre;}
public void setNombre(String nombre) {this.nombre = nombre;}
public String getApellidoPaterno() {return apellidoPaterno;}
public void setApellidoPaterno(String apellidoPaterno) {this.apellidoPaterno = apellidoPaterno;}
public String getApellidoMaterno() {return apellidoMaterno;}
public void setApellidoMaterno(String apellidoMaterno) {this.apellidoMaterno = apellidoMaterno;}
}

Notesé el uso de la clase Interna Usuario.ComposedIdKey en el parámetro de la anotación @PersistenceCapable y el uso de 2 anotaciones @PrimaryKey en las propiedades correspondientes.

Para realizar la consulta de un Objeto con una clave primaria compuesta debemos utilizar la sobrecarga del método getObjectById de la siguiente forma:


Usuario usuario=null;
 PersistenceManager pm = PMF.get().getPersistenceManager();
 Transaction tx = pm.currentTransaction();
 try{
 tx.begin();
 usuario = (Usuario) pm.getObjectById(new Usuario.ComposedIdKey(Usuario.ComposedIdKey.class.getName()+"::"+id+"::"+idJuzgado), false);
 tx.commit();
 }finally{
 if(tx.isActive()){
 tx.rollback();
 }
 pm.close();
 }

si tratas de utilizar el método getObjectById de la siguiente forma

pm.getObjectById(Usuario.class,new Usuario.ComposedIdKey(Usuario.ComposedIdKey.class.getName()+"::"+id+"::"+idJuzgado));

te arrojará una excepción parecida a la siguiente

javax.jdo.JDOUserException: Unable to create Object Identity for class “server.model.Usuario” since key is of an unsupported type (server.model.Usuario$ComposedIdKey

Fuentes:
http://www.datanucleus.org/products/datanucleus/jdo/primary_key.html
http://www.datanucleus.org/products/datanucleus/jdo/orm/compound_identity.html
http://es.wikipedia.org/wiki/Clave_primaria
http://book.javanb.com/using-and-understanding-java-data-objects/LiB0035.html

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: