How to introduce multi-column constraint with JPA annotations?

JavaJpaMapping

Java Problem Overview


I am trying to introduce a multi-key constraint on a JPA-mapped entity:

public class InventoryItem {
    @Id
    private Long id;

    @Version 
    private Long version;

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

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

Basically (product, serial) pair should be unique, but I only found a way to say that serial should be unique. This obviously isn't a good idea since different products might have same serial numbers.

Is there a way to generate this constraint via JPA or am I forced to manually create it to DB?

Java Solutions


Solution 1 - Java

You can declare unique constraints using the @Table(uniqueConstraints = ...) annotation in your entity class, i.e.

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

Note that this does not magically create the unique constraint in the database, you still need a DDL for it to be created. But seems like you are using some sort of automated tool for creating the database based on JPA entity definitions.

Solution 2 - Java

As already answered, multi-column index can be added using @Table annotation. However, columnNames needs to be the name of actual DB columns, not the class attribute. So, if the column is like the following:

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

Then the @Table annotation should be like the following

@Table(uniqueConstraints=
       @UniqueConstraint(columnNames = {"product_id", "serial"})) 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionplouhView Question on Stackoverflow
Solution 1 - JavapspView Answer on Stackoverflow
Solution 2 - JavaSJhaView Answer on Stackoverflow