terça-feira, 5 de dezembro de 2017

OneToMany - JPA

Temos o relacionamento OneToMany quando uma entidade aponta para uma lista de elementos de determinado tipo. Esse relacionamento pode ser implementado de forma unidirecional ou bidirecional dependendo da situação, e cada uma dessas formas tem suas vantagens e desvantagens.

No relacionamento unidirecional a implementação é mais simples, porém o acesso se dá por padrão e para efeitos de CRUD pela entidade que contém a lista. Abaixo temos a representação de um relacionamento OneToMany unidirecional:



Para implementarmos esse exemplo temos:

@Entity
public class Carro
{
          // outras propriedades da classe Carro
          ...

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "acessorio_id")
private List<Acessorio> lstAcessorio;

          // outras propriedades e métodos da classe Carro
          ...
}

          Não há uma propriedade do tipo Carro na classe Acessorio. Todas as operações do CRUD são feitas a partir da classe Carro. O JPA lida com isso muito bem e não há nada que precisemos fazer.

          Porém existem casos que o acesso precisa ser bidirecional, e isso torna as coisas um pouco mais trabalhosas. Veja o diagrama abaixo:




          Nesse relacionamento, eu tenho uma lista de itens dentro do pedido e cada item do pedido aponta para o pedido o qual faz parte. Como abaixo:

@Entity
public class Pedido
{
          // outras propriedades da classe Pedido
          ...

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "pedido")
@JoinColumn(name = "item_pedido_id")
private List<ItemPedido> lstItemPedido;
          // outras propriedades e métodos da classe Pedido
          ...
}
@Entity
public class ItemPedido
{
          // outras propriedades da classe ItemPedido
          ...

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "pedido_id")
private Pedido pedido;
          // outras propriedades e métodos da classe ItemPedido
          ...
}

Note que foi adicionado a propriedade mappedBy = "pedido" na anotação da lista de itens na classe Pedido. Quando ocorre o relacionamento bidirecional, o JPA começa a ter alguns problemas para garantir a integridade dos dados na hora de criar e remover os objetos da lista, pois ele não consegue sozinho adicionar em cada elemento da lista de itens o pedido a qual ele pertence. É preciso que nós cuidemos dessa parte. Devemos fazer com que toda vez que formos adicionar um novo item a lista de itens do pedido, o pedido seja também adicionado ao item da lista. Existe basicamente dois locais para fazermos isso, no Front Controller ou na entidade que contém a lista. Vou mostrar o exemplo dos métodos que podem ser adicionados a entidade Pedido.

public ItemPedido addItemPedido ( ItemPedido itemPedido ) {
     getItemPedido().add( itemPedido );
     itemPedido.setPedido( this );

     return itemPedido;
}

public ItemPedido removeItemPedido ( ItemPedido itemPedido ) {
     getItemPedido().remove( itemPedido );
     itemPedido.setPedido( null );

     return itemPedido;
}
          
        Sempre que formos adicionar ou remover um item da lista, devemos fazer isso usando a instancia do pedido, e claro com a lista já devidamente instanciada.

Pronto, dessa forma temos um relacionamento OneToMany bidirecional.


Nenhum comentário:

Postar um comentário