DEV Community

Samuel Luiz
Samuel Luiz

Posted on • Edited on

3

JPA Cheatsheet: visualizando relacionamentos

Modelar e descrever relações entre entidades pode ser uma dificuldade para desenvolvedores iniciantes, mas no caso do JPA pode virar uma completa bagunça se não prestar a devida atenção. Quando aprendi esta tecnologia criei um pequeno guia pra me ajudar e me baseio nele até hoje quando estou com alguma dúvida.

OneToMany ou ManyToOne relationship

Regra: geralmente, o lado “many” é o dono da relação.

Exemplo: Cliente e Pedido.

Perguntas a se fazer:

  • Um cliente pode ter quantos pedidos?
  • Um pedido pode pertencer a quantos clientes?
  • Eu preciso saber quais os pedidos do cliente?
  • Eu preciso saber qual o cliente de cada pedido?
  • Quem é o dono do relacionamento?

Respostas:

  • [x] Um cliente pode ter vários pedidos. (OneToMany)
  • [x] Um pedido pode pertencer a apenas um cliente. (ManyToOne)
  • [x] Eu não preciso saber os pedidos de cada cliente, mas preciso saber o cliente de cada pedido. (Unidirecional)
  • [x] O pedido é o dono do relacionamento.

Portanto, chegamos a conclusão de que um cliente pode ter vários pedidos, mas um pedido pertence a apenas um cliente.

Na classe pedido, nós declaramos o atributo cliente com as anotações:

  • @ManyToOne (pois vários pedidos (Many) podem ter apenas um cliente (ToOne)
  • @JoinColumn(name = “cliente_id”) para criar uma coluna no banco de dados com o id do cliente

Classe Pedido:

@ManyToOne
@JoinColumn(name = cliente_id)
private Cliente cliente;
Enter fullscreen mode Exit fullscreen mode

Na classe cliente, nós declaramos e INSTANCIAMOS uma coleção de pedidos com as anotações:

  • @JsonIgnore (para a resposta em json da requisição HTTP ignorar esta lista e não criar um loop de pedidos com cliente e cliente com pedidos, gerando stack overflow, afinal nós não precisamos saber os itens). Uma alternativa ao JsonIgnore pode ser usar DTO’s.

  • @OneToMany(mappedBy = “cliente”) pois um cliente (One) pode ter vários pedidos (ToMany), o parâmetro mappedBy serve para mapear o atributo da classe Pedido (deve ser exatamente igual ao atributo declarado na classe)

Classe Cliente:

@OneToMany(mappedBy = cliente)
private List<Pedido> pedidos;
Enter fullscreen mode Exit fullscreen mode

ManyToMany relationship

Exemplo: Um produto pode pertencer a várias categorias, e uma categoria possui vários produtos.

Perguntas a se fazer:

  • Um produto pode pertencer a quantas categorias?
  • Uma categoria pode possuir quantos produtos?
  • Eu preciso saber quais produtos uma categoria possui?
  • Eu preciso saber a quais categorias um produto pertence?
  • Quem é o dono do relacionamento?

Respostas:

  • [x] Um produto pode pertencer a varias categorias. (ManyToMany)
  • [x] Uma categoria pode possuir vários produtos. (ManyToMany)
  • [x] Eu preciso saber quais produtos uma categoria possui, e também saber a quais categorias um produto pertence. (Bidirecional)
  • [x] O produto é o dono do relacionamento.

Portanto, chegamos a conclusão de que um produto pode pertencer a várias categorias, e uma categoria pode possuir vários produtos. Nesse caso, devemos criar uma tabela de associação usando o @JoinTable. Como o Produto possui essa anotação, é implícito que o Produto é o dono da relação.

Na classe produto, declaramos e INSTANCIAMOS uma coleção de categorias com as anotações:

  • @ManyToMany (pois vários produtos (Many) podem ser de várias categorias (ToMany)
  • @JoinTable (para criar uma nova tabela)
  • @JoinColumn (dentro do @JoinTable para criar as colunas)

Classe Produto:

@ManyToMany
@JoinTable(name = "tb_product_category",
joinColumns = @JoinColumn(name = "product_id"),
inverseJoinColumns = @JoinColumn(name = "category_id"))
private Set<Category> categories = new HashSet<>();
Enter fullscreen mode Exit fullscreen mode

Na classe category, declaramos e INSTANCIAMOS uma coleção de produtos com as anotações:

  • @ManyToMany(mappedBy = “categories”) para mapear a coleção de categorias da classe Produto e indicar que o dono do relacionamento é o Produto.

Classe Categoria:

@ManyToMany(mappedBy = "categories")
private Set<Product> products = new HashSet<>();
Enter fullscreen mode Exit fullscreen mode

OneToOne relationship

Exemplo: Um usuário pode ter um perfil associado, e um perfil pertence a apenas um usuário.

Perguntas a se fazer:

  • Um usuário pode ter quantos perfis?
  • Um perfil pode pertencer a quantos usuários?
  • Eu preciso saber o perfil de cada usuário?
  • Eu preciso saber o usuário associado a cada perfil?
  • Quem é o dono do relacionamento?

Respostas:

  • [x] Um usuário pode ter apenas um perfil. (OneToOne)
  • [x] Um perfil pode pertencer a apenas um usuário. (OneToOne)
  • [x] Eu preciso saber o perfil de cada usuário, e também o usuário associado a cada perfil. (Bidirecional)
  • [x] O usuário é o dono do relacionamento.

Portanto, concluímos que um usuário pode ter apenas um perfil, e um perfil pertence a apenas um usuário. Nesse caso, o usuário será o dono do relacionamento.

Na classe Usuario, declaramos o atributo perfil com as anotações:

@OneToOne(mappedBy = "usuario")
private Perfil perfil;
Enter fullscreen mode Exit fullscreen mode

Na classe Perfil, declaramos o atributo usuario com as anotações:

@OneToOne
@JoinColumn(name = "usuario_id")
private Usuario usuario;
Enter fullscreen mode Exit fullscreen mode

Observe que a anotação @OneToOne é utilizada em ambas as classes para indicar a relação One-To-One. A classe Perfil possui a anotação @JoinColumn para criar uma coluna no banco de dados com o id do usuário, que será usado para mapear o relacionamento. A classe Usuario utiliza a anotação mappedBy no atributo perfil para indicar que o relacionamento é mapeado pelo atributo usuario na classe Perfil.

Dessa forma, temos uma relação One-To-One entre Usuario e Perfil, em que um usuário pode ter apenas um perfil e um perfil pertence a apenas um usuário.

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more