Ola PessoAll!
Dando continuidade a temática de Persistência de dados, demonstrarei neste post, a implementação do relacionamento de cardinalidade 1:N (1 para N), o que implica o uso das annotations: @ManyToOne e @OneToMany.
Como já visto em posts anteriores, o uso de frameworks ORM agregam bastante facilidade e agilidade no desenvolvimento de aplicações; sabe-se que modelagens de dados propiciam a coexistência de sua estrutura, ou seja, priorizam (na maioria das vezes) o uso de relacionamentos, ou seja, objetos de banco não têm muita significância quando isolados.
Para a obtenção de informações coesas, bem como, significantes ao contexto de negócio, o uso de relacionamentos é imprescindível, desta forma, saber manipular os relacionamentos no contexto ORM é significativamente importante.
Segundo a documentação da especificação JEE 6 (http://docs.oracle.com/javaee/6/tutorial/doc/bnbqa.html#bnbqh), tem-se:
- One-to-many: An entity instance can be related to multiple instances of the other entities. A sales order, for example, can have multiple line items. In the order application, Order would have a one-to-many relationship with LineItem. One-to-many relationships use the javax.persistence.OneToMany annotation on the corresponding persistent property or field.
- Many-to-one: Multiple instances of an entity can be related to a single instance of the other entity. This multiplicity is the opposite of a one-to-many relationship. In the example just mentioned, the relationship to Order from the perspective ofLineItem is many-to-one. Many-to-one relationships use the javax.persistence.ManyToOne annotation on the corresponding persistent property or field.
Será utilizado o projeto Persistência constituídos nos posts anteriores para a implementação. Ao trabalho!
A MODELAGEM
No nosso banco de dados que abrigava o cadastro de produtos, criaremos a tabela Categoria e o devido relacionamento com produto, conforme modelagem:
O script para a criação da tabela Categoria e inclusão do relacionamento em Produto, segue:
create table categoria ( id_categoria serial, nome varchar(45) not null, descricao varchar(200), fg_ativo boolean, primary key (id_categoria)); alter table produto add column id_categoria integer; alter table produto add constraint categoria_id_categoria_fk foreign key (id_categoria) references categoria (id_categoria);
IMPLEMENTAÇÃO
Feitas as alterações procederemos ao mapeamento, que deverá ser constituído da seguinte forma:
Produto:
package br.com.serjava.persistencia.entity;
//imports omitidos
@Entity
@Table(name="produto")
@SequenceGenerator(name="produto_id_produto_seq", sequenceName="produto_id_produto_seq", allocationSize=1)
public class Produto implements Serializable {
private static final long serialVersionUID = -8121617132071401241L;
@Id
@GeneratedValue(generator="produto_id_produto_seq", strategy=GenerationType.SEQUENCE)
@Column(name="id_produto")
private Integer idProduto;
@Column(name="nm_produto")
private String nomeProduto;
@Column(name="quantidade")
private Integer quantidade;
@Column(name="valor")
private Double valor;
//relacionamento com categoria
@ManyToOne
@JoinColumn(name="id_categoria", referencedColumnName="id_categoria")
private Categoria category;
//getters and setters
Categoria:
package br.com.serjava.persistencia.entity;
//imports omitidos
@Entity
@Table(name="categoria")
@SequenceGenerator(name="categoria_id_categoria_seq", sequenceName="categoria_id_categoria_seq", allocationSize=1)
public class Categoria implements Serializable {
private static final long serialVersionUID = -8765631845563878481L;
@Id
@GeneratedValue(generator="categoria_id_categoria_seq", strategy=GenerationType.SEQUENCE)
@Column(name="id_categoria")
private Long idCategoria;
@Column(name="nome", nullable=false)
private String nome;
@Column(name="descricao")
private String descricao;
@Column(name="fg_ativo")
private Boolean ativo;
@OneToMany(mappedBy="categoria")
private List<Produto> listaProdutos;
//getters and setters
Observe que na entidade Produto temos um objeto de Categoria, pois, de acordo com o modelo elaborado, um produto tem uma categoria; já na entidade Categoria, note a existência de uma lista de Produtos, o que indica que uma categoria pode estar associada a N produtos.
Atenção! O atributo mappedBy presente na annotation @OneToMany, presente na entidade Categoria, deve conter a nomenclatura dada ao objeto que referencia-se a uma categoria na entidade Produto!
Na entidade Produto, temos a anotação @JoinColumn (você deve estar pensando: Nossa é aqui que o join é feito? SIM!), seus atributos name e referencedColumnName significam, respectivamente, o nome do atributo correspondente a foreign key de categoria na tabela produto (no banco de dados) e o nome da primary key representativa da tabela Categoria!
O próximo passo é a criação do objeto de acesso a dados (DAO) para a entidade Categoria. Felizmente nosso projeto está usando a arquitetura DAO Genérico, o que nos poupará bastante trabalho. A criação de CategoriaDAO e CategoriaDAOImpl deverá ser feita de forma análoga a Produto, para não ser repetitivo, verifique nos posts anteriores (em caso de dúvidas consulte: Persistência - DAO Genérico).
Para efetivarmos o relacionamento, criaremos 2 Produtos e os vincularemos a uma dada Categoria, na classe main:
public static void main(String... args) {
ProdutoDAO produtoDAO = new ProdutoDAOImpl();
CategoriaDAO categoriaDAO = new CategoriaDAOImpl();
Categoria categoria = new Categoria();
categoria.setNome("Livros Informática");
categoria.setDescricao("Livros de desenvolvimento, banco de dados...");
categoria.setAtivo(true);
//Categoria é salva no banco e recuperada - uso do merge, ou seja, tem-se o objeto categoria
// sincronizado no contexto de persistência
categoria = categoriaDAO.save(categoria);
Produto produto = new Produto();
produto.setNomeProduto("Head First - Java");
produto.setQuantidade(11);
produto.setValor(99.99);
//atribui a cateogira Livros Informática ao produto
produto.setCategoria(categoria);
Produto produto2 = new Produto();
produto2.setNomeProduto("Head First - Servlets and JSP");
produto2.setQuantidade(55);
produto2.setValor(128.99);
//atribui a cateogira Livros Informática ao produto
produto2.setCategoria(categoria);
//salva-se os produtos
produtoDAO.save(produto);
produtoDAO.save(produto2);
List<Produto> listaProdutosCadastrados = produtoDAO.getAll(Produto.class);
for (Produto p : listaProdutosCadastrados) {
System.out.println(p.getNomeProduto());
}
}
O resultado esperado é a inserção de 2 produtos vínculados a categoria criada. Vejamos o resultado no banco:
Observe que foi criada a Categoria 3 - Livros Informática, e os produtos 22 e 23, vinculados a esta categoria, pelo código 3!
Espero que tenham gostado!





