JPA Key composed for .find () [closed]

1

I have an entity with compound keys, how can I do the .find ()

Obj p = XPersistence.getManager().find(Obj.class, ??clave)??;

p.setCampoDesc("hola");

XPersistence.getManager().getTransaction().commit();

the class has

    @Id
    @Column(name="xxxx", columnDefinition="smallint")   
    private Integer xxxx;
    @Id
    @Column(name="xxx", columnDefinition="char(5)",length=5)
    private String xxxx;
    @Id 
    @Column(name="xxxx", columnDefinition="char(5)",length=5)
    private String xxx;
    @Id
    @Column(name="xxxx", columnDefinition="char(7)",length=7)
    private String xxx;
    
asked by Adrian.Aguirre 28.03.2018 в 13:17
source

2 answers

2

Use a composite primary key, implemented in a specific class. For example:

@Entity
public class MiClase{
    @EmbeddedId
    private MiClavePrimaria miClavePrimaria;
    @Column(...)
    private String campo1;
    ...
    @Column(...)
    private String campoN;
}

@Embeddable
public class MiClavePrimaria {

    @Column
    private String campoClavePrimaria1;
    ...
    @Column
    private String campoClavePrimariaN;

}

And to do the find:

MiClavePrimaria clave = new MiClavePrimaria();
clave.setCampoClavePrimaria1(valor1);
...
clave.setCampoClavePrimariaN(valorN);
MiClase p = XPersistence.getManager().find(MiClase.class, clave );
    
answered by 28.03.2018 / 14:09
source
1

The response of @pablo is correct. I just write this answer to provide more information about the possible use of JPA annotations.

First, to implement a composite primary key (from now on PK), it is necessary to have a class to part marked as @Embeddable . Let's assume for our examples that we have an entity called A that has a PK composed of two integers, such that:

@Entity
@Table(name="tmp_a")
public class A {
    @EmbeddedId
    private PK_A clave;
    //¿Como pongo los atributos de la PK en la clase?

    private String atributoNoDeClavePrimaria;
}

@Embeddable
public class PK_A {
    public int id1, id2;
    //getters, setters, hashCode y equals
}

The structure of the table would be the following:

CREATE TABLE tmp_a(
    id1 INT NOT NULL,
    id2 INT NOT NULL,
    atributoNoDeClavePrimaria VARCHAR(50) NULL,
    PRIMARY KEY(id1, id2)
);

Now, what if I decide that I do not like the names id1 e id2 ? I want, so that everything is clearer in the Java code, call them codProducto and codFactura . These names are no longer the same as in the database, how can I tell JPA that those attributes are actually the table's PK? For this we have the @MapsId(nombre_de_atributo) tag. In our example, the class A would look like this:

@Entity
@Table(name="tmp_a")
public class A {
    @EmbeddedId
    private PK_A clave;

    @Column(name="id1")
    @MapsId("codProducto")
    private int codProducto; 
    //Notese que aqui tambien he cambiado el nombre de la columna

    @Column(name="id2")
    @MapsId("codFactura")
    private int codFactura;

    ...
}

But we can still improve. Since we have put products and invoices as an example, we can put a column of a station as a many-to-one relation, which would allow us to bring the objects with the relation (we assume that there are created two entities Producto and Factura ):

@Entity
@Table(name="tmp_a")
public class A {
    @EmbeddedId
    private PK_A clave;

    @JoinColumn(name="id1", insertable=true, updatable=true)
    @MapsId("codProducto")
    @ManyToOne
    private Producto producto;

    @JoinColumn(name="id2", insertable=true, updatable=true)
    @MapsId("codFactura")
    @ManyToOne
    private Factura factura;

    ...
}

And all without having to write more annotations than @Embeddable in the class that represents the PK.

    
answered by 28.03.2018 в 15:06