¿Cómo introducir la restricción de varias columnas con anotaciones JPA?

91

Estoy tratando de introducir una restricción de claves múltiples en una entidad mapeada por JPA:

public class InventoryItem {
    @Id
    private Long id;

    @Version 
    private Long version;

    @ManyToOne
    @JoinColumn("productId")
    private Product product;

    @Column(nullable=false);
    private long serial;
}

Básicamente, el par (producto, serie) debería ser único, pero solo encontré una manera de decir que la serie debería ser única. Obviamente, esto no es una buena idea ya que diferentes productos pueden tener los mismos números de serie.

¿Hay alguna forma de generar esta restricción a través de JPA o me veo obligado a crearla manualmente en la base de datos?

plouh
fuente

Respuestas:

191

Puede declarar restricciones únicas usando la @Table(uniqueConstraints = ...)anotación en su clase de entidad, es decir

@Entity
@Table(uniqueConstraints={
    @UniqueConstraint(columnNames = {"productId", "serial"})
}) 
public class InventoryItem {
    ...
}

Tenga en cuenta que esto no crea mágicamente la restricción única en la base de datos, aún necesita un DDL para que se cree. Pero parece que está utilizando algún tipo de herramienta automatizada para crear la base de datos basada en definiciones de entidad JPA.

psp
fuente
1
¿Se necesita este tipo de cosas para una base de datos existente con restricciones ya establecidas?
Rob
Creo que la restricción se creará porque el proveedor de JPA está creando la base de datos.
AlanObject
¿La unicidad es para la columna (productId) y la columna (serial) o para la restricción de 2 columnas en total (productId, serial)?
P Satish Patro
69

Como ya se respondió, el índice de varias columnas se puede agregar mediante la @Tableanotación. Sin embargo, columnNamesdebe ser el nombre de las columnas DB reales, no el atributo de clase. Entonces, si la columna es como la siguiente:

@Column(name="product_id")
Long productId;

Entonces la @Tableanotación debería ser como la siguiente

@Table(uniqueConstraints=
       @UniqueConstraint(columnNames = {"product_id", "serial"}) 
SJha
fuente
10
Esta es una aclaración muy importante: nombres de tablas y no nombres de objetos.
Calabacin
1
¿La unicidad es para la columna (productId) y la columna (serial) o para la restricción de 2 columnas en total (productId, serial)?
P Satish Patro
Kotlin: Eche un vistazo a esta respuesta para encontrar un ejemplo de kotlin: stackoverflow.com/a/47000044/285431
Dirk
Error de sintaxis. Falta el paréntesis de cierre en la anotación @Table.
Evvo