Chaves primárias compostas na JPA

Chaves primárias compostas na JPA

1. Introdução

Neste tutorial, aprenderemos sobre chaves primárias compostas e as anotações correspondentes em JPA.

2. Chaves primárias compostas

Uma chave primária composta - também chamada de chave composta - é uma combinação de duas ou mais colunas para formar uma chave primária para uma tabela.

Em JPA, temos duas opções para definir as chaves compostas: As anotações@IdClasse@EmbeddedId.

Para definir as chaves primárias compostas, devemos seguir algumas regras:

  • A classe de chave primária composta deve ser pública

  • Ele deve ter um construtor sem argumento

  • Deve definir os métodosequals()ehashCode()

  • Deve serSerializable

3. A anotaçãoIdClass

Digamos que temos uma tabela chamadaAccount e ela tem duas colunas -accountNumber, accountType – que formam a chave composta. Agora temos que mapear na JPA.

De acordo com a especificação JPA, vamos criar uma classeAccountId com estes campos de chave primária:

public class AccountId implements Serializable {
    private String accountNumber;

    private String accountType;

    // default constructor

    public AccountId(String accountNumber, String accountType) {
        this.accountNumber = accountNumber;
        this.accountType = accountType;
    }

    // equals() and hashCode()
}

A seguir, vamos associar a classeAccountId à entidadeAccount.

Para fazer isso, precisamos anotar a entidade com a anotação@IdClass. Devemos também declarar os campos da classeAccountId na entidadeAccounte anotá-los com@Id:

@Entity
@IdClass(AccountId.class)
public class Account {
    @Id
    private String accountNumber;

    @Id
    private String accountType;

    // other fields, getters and setters
}

4. A anotaçãoEmbeddedId

@EmbeddedId é uma alternativa para a anotação@IdClass.

Vamos considerar outro exemplo onde temos que persistir algumas informações de aBook comtitleelanguage como os campos de chave primária.

Neste caso, a classe de chave primária,BookId, must be annotated with @Embeddable:

@Embeddable
public class BookId implements Serializable {
    private String title;
    private String language;

    // default constructor

    public BookId(String title, String language) {
        this.title = title;
        this.language = language;
    }

    // getters, equals() and hashCode() methods
}

Então, precisamos incorporar essa classe na entidadeBook usando@EmbeddedId:

@Entity
public class Book {
    @EmbeddedId
    private BookId bookId;

    // constructors, other fields, getters and setters
}

5. @IdClass vs@EmbeddedId

Como acabamos de ver, a diferença na superfície entre esses dois é que com@IdClass, tivemos que especificar as colunas duas vezes - uma vez emAccountIde novamente emAccount. Mas, com@EmbeddedId não.

Existem algumas outras vantagens, no entanto.

Por exemplo, essas diferentes estruturas afetam as consultas JPQL que escrevemos.

Por exemplo, com@IdClass, a consulta é um pouco mais simples:

SELECT account.accountNumber FROM Account account

Com@EmbeddedId, temos que fazer um percurso extra:

SELECT book.bookId.title FROM Book book

Além disso,@IdClass can be quite useful in places where weare using a composite key class that we can’t modify.

Finalmente, se vamos acessar partes da chave composta individualmente, podemos usar@IdClass,, masin places where we frequently use the complete identifier as an object, @EmbeddedId is preferred.

6. Conclusão

Neste artigo rápido, exploramos chaves primárias compostas no JPA.

Como sempre, o código completo para este artigo pode serfound over on Github.