Este material foi desenvolvimento com o
objeto de estudar o recurso de geração automática do banco oferecido pelo Java
Persistence API pelo framework toplink. O estudo tratará das possibilidades
uni e bidirecional das associações @ManyToOne e @OneToMany no modelo e seus
respectivos reflexos na base de dados.
Como optar entre relações
unidirecionais ou bidirecionais?
Em alguns modelos, talvez não seja
necessário que o relacionamento entre dois objetos seja bidirecional. Isto
ocorre quando um objeto não precisa conhecer o outro lado da associação. Um
caso bem simples seria do relacionamento entre as entidades Militar e
PostoGraduacao. Um objeto Militar possui um único
PostoGraduacao (por exemplo, 3º Sargento ou 1º Tenente) e um objeto
PostoGraduacao está associado com vários objetos Militar.

Observe que, na maioria das abstrações
dos sistemas existentes, o objeto Militar precisa conhecer o objeto
PostoGraduacao. Porém, um PostoGraduacao não precisa conhecer
quais militares ele está associado. Suponha que você levantasse
(instanciasse na memória) uma listagem (por exemplo, através da coleção
List<PostoGraduacao>) do objeto PostoGraduacao para compor
um ComboBox. Seria impraticável se cada um desses objetos
PostoGraduacao possuíssem a listagem completa dos objetos Militar
associados, ou seja, o objeto “3º Sargento” com sua listagem de
militares associados – objetos “João”, “Pedro”, “Maria”, etc. Isso
significa que neste relacionamento @ManyToOne (muitos para um, do ponto
de vista do objeto Militar), somente o objeto Militar terá o
atributo e a respectiva anotação para conhecer o relacionamento. O objeto
PostoGraduacao não precisa (na verdade, não deve) conhecer quais
militares estão associados a ele.
Existe também outro fator que deve ser
considerado ao optar entre relacionamentos uni e bidirecionais: o acoplamento
desnecessário entre os objetos e pacotes. Dois objetos talvez não precisem ter
relacionamento bidirecional e neste caso, ao optar pelo relacionamento
unidirecional, estaremos evitando um desacoplamento inviável e desnecessário.
No caso de objetos dispostos em pacotes distintos, a situação torna-se mais
crítica. Veja o exemplo fictício mostrado no diagrama abaixo:

O relacionamento entre dois pacotes não
pode (não é recomendado) conter dependência mútua. Ou seja, se o
relacionamento entre Militar e PostoGraduacao for bidirecional,
significa que o objeto Militar depende de PostoGraduacao e que o
objeto PostoGraduacao depende de Militar. Quando estes objetos
estão em pacotes diferentes, significa que o pacote model.one depende
do pacote model.two que o pacote model.two também depende do
pacote model.one. Este tipo de situação é inviável do ponto de vista da
orientação a objetos. Em casos como este, o relacionamento bidirecional deve
ser evitado ou a distribuição dos objetos nos pacotes deve ser
reestruturada.
Relacionamento @ManyToOne
unidirecional
Vamos ao caso prático! O contexto
abordado anteriormente serve como caso prático para esse tipo de
relacionamento. O diagrama abaixo retrata a associação pertinente entre os
objetos Militar e PostoGraduacao. Como já explicado, um
Militar precisa conhecer seu PostoGraduacao, porém o inverso não
é verdadeiro.

Isso mostra claramente que no caso do
Militar, existe a necessidade da anotação @ManyToOne, ou seja,
existem muitos militares para um único posto/graduação. A seguir temos os
códigos necessários para o desenvolvimento deste estudo.
O arquivo persistence.xml segue
abaixo:
<?xml
version="1.0"
encoding="UTF-8"?>
<persistence
version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit
name="default"
transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<class>model.manytoone.PostoGraduacao</class>
<class>model.manytoone.Militar</class>
<properties>
<property
name="toplink.jdbc.user"
value="root"
/>
<property
name="toplink.jdbc.password"
value="root"
/>
<property
name="toplink.jdbc.url"
value="jdbc:mysql://localhost:3306/ejb"
/>
<property
name="toplink.jdbc.driver"
value="com.mysql.jdbc.Driver"/>
<property
name="toplink.ddl-generation"
value="create-tables"/>
</properties>
</persistence-unit>
</persistence>
Observe a configuração do arquivo. Com
os parâmetros toplink.jdbc.user e toplink.jdbc.password são
definidos, respectivamente, os valores do usuário e senha de acesso ao banco.
O parâmetro toplink.jdbc.url define o valor da string de conexão, o
valor de toplink.jdbc.driver define o driver utilizado para acessar o
banco (no caso, para o banco MySQL) e o parâmetro toplink.dll-generation
define o algoritmo de geração automática do banco. Neste caso, as tabelas
são criadas automaticamente. Através das propriedades class, os objetos
persistidos são definidos.
Abaixo, o arquivo do objeto
PostoGraduacao.java:
package
model.manytoone;
import
java.io.Serializable;
import
javax.persistence.Entity;
import
javax.persistence.Table;
import
javax.persistence.Id;
import
javax.persistence.GeneratedValue;
import
javax.persistence.Column;
@Entity(
name = "PostoGraduacao"
)
@Table(
name =
"postosgraduacoes"
)
public
class
PostoGraduacao
implements
Serializable {
private
static
final
long
serialVersionUID
= 1379657866927537568L;
@Id
@GeneratedValue
@Column(
name = "id"
)
private
Long
id;
@Column(
name = "descricao" ,
nullable = false
)
private
String
descricao;
public
Long getId() {
return
id;
}
public
void setId(Long
id) {
this.id
= id;
}
public
String getDescricao() {
return
descricao;
}
public
void
setDescricao(String descricao) {
this.descricao
= descricao;
}
}
A definição das anotações pode ser
entendida pelo conteúdo abaixo:
@Entity – define o nome da
entidade
@Table – define o nome da tabela do
banco de dados associada com essa entidade
@Id – define que o atributo é a chave
primária na tabela
@GeneratedValue – define que o valor do
atributo será gerado automaticamente pelo banco
@Column – define as propriedades do
atributo no banco de dados
Observe que neste caso, conforme
planejado, não existe nenhuma ligação com o objeto Militar. Vamos agora
analisar o código fonte Militar.java:
package
model.manytoone;
import
java.io.Serializable;
import
javax.persistence.Entity;
import
javax.persistence.Table;
import
javax.persistence.Id;
import
javax.persistence.GeneratedValue;
import
javax.persistence.Column;
import
javax.persistence.ManyToOne;
import
javax.persistence.JoinColumn;
@Entity(
name = "Militar"
)
@Table(
name = "militares"
)
public
class Militar
implements
Serializable {
private
static
final
long
serialVersionUID
= 2485833714032900145L;
@Id
@GeneratedValue
@Column(
name = "id"
)
private
Long
id;
@Column(
name = "nome"
)
private
String
nome;
/**
*
Nesta
tabela
haverá
um
campo
chamado
postograduacao_id
foreign
key
*
do
campo
id
na
tabela
postosgraduacoes.
*/
@ManyToOne(
optional = false
)
@JoinColumn(
name =
"postograduacao_id" ,
referencedColumnName =
"id"
)
private
PostoGraduacao
postoGraduacao;
public
Long getId() {
return
id;
}
public
void setId(Long
id) {
this.id
= id;
}
public
String getNome() {
return
nome;
}
public
void
setNome(String nome) {
this.nome
= nome;
}
public
PostoGraduacao getPostoGraduacao() {
return
postoGraduacao;
}
public
void
setPostoGraduacao(PostoGraduacao postoGraduacao)
{
this.postoGraduacao
= postoGraduacao;
}
}
Veja que neste caso, além das anotações
comuns, existe a anotação @ManyToOne qualificando o atributo
PostoGraduacao como relacionamento entre as tabelas no banco de dados.
Pela anotação @JoinColumn são especificados: (1) o nome do campo de chave
estrangeira que será criado na tabela militares responsável por
armazenar a chave primária da tabela postosgraduacoes (parâmetro
name); (2) o nome da própria chave primária da tabela
postosgraduacoes (parâmetro referencedColumnName).
Esses objetos poderão ser inseridos no
banco através de uma unidade de persistência. Abaixo temos o código do arquivo
AbstractDAO.java:
package
dao;
import
javax.persistence.EntityManager;
import
javax.persistence.EntityManagerFactory;
import
javax.persistence.Persistence;
import
javax.persistence.PersistenceException;
import
javax.persistence.PersistenceUnit;
@PersistenceUnit
public
class AbstractDAO
{
private
static
EntityManagerFactory
emf =
Persistence
.createEntityManagerFactory("default");
private
static
EntityManager em
=
emf.createEntityManager();
private
static
AbstractDAO
dao;
public
AbstractDAO() { }
public
static
AbstractDAO getInstance() {
if
(dao ==
null)
dao =
new
AbstractDAO();
return
dao;
}
public
void
create(Object object)
throws
PersistenceException {
try
{
em.getTransaction().begin();
em.persist(object);
em.getTransaction().commit();
em.clear();
}
catch (Exception
e) {
throw
new
PersistenceException("Não foi possível criar o
objeto!");
}
}
}
Observe que este objeto foi criado com
base no pattern Singleton e que só possui um método de cadastrado –
chamado de create. Com esta unidade de persistência, podemos concluir
nosso exemplo com um código de teste, chamado de TestDriver.java:
package
engine;
import
model.manytoone.*;
import
dao.AbstractDAO;
public
class TestDriver
{
public
static
void main(String
args[]) {
PostoGraduacao
grad = new
PostoGraduacao();
grad.setDescricao(
"2º Tenente"
);
Militar
mil1 = new
Militar();
mil1.setNome(
"Guilherme"
);
mil1.setPostoGraduacao( grad
);
Militar
mil2 = new
Militar();
mil2.setNome(
"João" );
mil2.setPostoGraduacao( grad
);
AbstractDAO.getInstance().create(
grad );
AbstractDAO.getInstance().create(
mil1 );
AbstractDAO.getInstance().create(
mil2 );
}
}
Este é um simples exemplo para testar o
funcionamento do estudo. Após executar esse teste, teremos os resultados
apresentados abaixo no MySQL. Atenção: deve ser criado um banco de nome ejb
no banco de dados. Atente-se também que o usuário root possui a
senha root.

Conforme previsto, a tabela militares
possui um campo postograduacao_id que referencia o campo id
da tabela postosgraduacoes. A tabela sequence é responsável
pela geração dos id automaticamente. Os dados inseridos podem ser
visualizados abaixo:

Este foi um caso de relacionamento
unidirecional para @ManyToOne. Os demais exemplos não trarão os códigos
dos arquivos persistence.xml e AbstractDAO.java, pois estes
podem ser facilmente adaptados de acordo com o estudo. Especificamente, o
arquivo AbstractDAO.java não precisará ser modificado. Atente-se na
inserção de novas chaves <class></class> no arquivo
persistence.xml para que o mesmo comporte as classes criadas nos
próximos exemplos.
Relacionamento @ManyToOne
bidirecional
Vamos ver agora um caso em que o
relacionamento @ManyToOne precisa ser bidirecional – ou seja, neste
caso, os objetos precisam tomar conhecimento da existência do relacionamento
com o outro objeto.

Neste caso, o objeto Militar
possui vários documentos e o objeto Documento pertence a um único
Militar. Isso ocorre por que na prática, uma pessoa precisa saber quais
são os seus documentos e um documento possui a identificação da pessoa (sabe
de quem ele é). A anotação @ManyToOne deve ficar no objeto
Documento e, como o objeto Militar também precisa conhecer seus
documentos, terá uma anotação @OneToMany. Abaixo temos o código do
arquivo Militar.java – observe que este foi modificado, porém ainda
mantém sua associação com o objeto PostoGraduacao.
package
model.manytoone;
import
java.io.Serializable;
import
java.util.List;
import
javax.persistence.Entity;
import
javax.persistence.Table;
import
javax.persistence.Id;
import
javax.persistence.GeneratedValue;
import
javax.persistence.Column;
import
javax.persistence.ManyToOne;
import
javax.persistence.OneToMany;
import
javax.persistence.JoinColumn;
@Entity(
name = "Militar"
)
@Table(
name = "militares"
)
public
class Militar
implements
Serializable {
private
static
final
long
serialVersionUID
= 2485833714032900145L;
@Id
@GeneratedValue
@Column(
name = "id"
)
private
Long
id;
@Column(
name = "nome"
)
private
String
nome;
@ManyToOne(
optional = false
)
@JoinColumn(
name =
"postograduacao_id" ,
referencedColumnName =
"id"
)
private
PostoGraduacao
postoGraduacao;
@OneToMany(
mappedBy = "meuDono"
)
private
List<Documento>
documentos;
public
Long getId() {
return
id;
}
public
void setId(Long
id) {
this.id
= id;
}
public
String getNome() {
return
nome;
}
public
void
setNome(String nome) {
this.nome
= nome;
}
public
PostoGraduacao getPostoGraduacao() {
return
postoGraduacao;
}
public
void
setPostoGraduacao(PostoGraduacao postoGraduacao)
{
this.postoGraduacao
= postoGraduacao;
}
public
void
setDocumentos(List<Documento> documentos)
{
this.documentos
= documentos;
}
public
List<Documento> getDocumentos() {
return
documentos;
}
}
A única alteração em Militar
corresponde ao atributo documentos que é uma coleção
List<Documento> qualificada pela anotação @OneToMany.
Observe a existência do parâmetro mappedBy que indica o nome do
atributo no objeto Documento que está associado a este relacionamento –
no caso meuDono, que representa justamente o objeto “dono” do
documento. O fato de se trabalhar com uma coleção indica que este objeto
possui muitos documentos, exatamente como mostrado no modelo. À critério de
entendimento, a anotação @OneToMany indica que existe um objeto
Militar para muitos objetos Documento.
Veremos agora o arquivo
Documento.java:
package
model.manytoone;
import
java.io.Serializable;
import
javax.persistence.Entity;
import
javax.persistence.Table;
import
javax.persistence.Id;
import
javax.persistence.GeneratedValue;
import
javax.persistence.Column;
import
javax.persistence.ManyToOne;
import
javax.persistence.JoinColumn;
@Entity(
name = "Documento"
)
@Table(
name = "documentos"
)
public
class Documento
implements
Serializable {
private
static
final
long
serialVersionUID
= 7563299527052904816L;
@Id
@GeneratedValue
@Column(
name = "id"
)
private
Long
id;
@Column(
name = "descricao" ,
length = 50, nullable =
false
)
private
String
descricao;
@ManyToOne(
optional = false
)
@JoinColumn(
name = "militar_id" ,
referencedColumnName =
"id"
)
private
Militar
meuDono;
public
Long getId() {
return
id;
}
public
void setId(Long
id) {
this.id
= id;
}
public
String getDescricao() {
return
descricao;
}
public
void
setDescricao(String descricao) {
this.descricao
= descricao;
}
public
void
setMeuDono(Militar meuDono) {
this.meuDono
= meuDono;
}
public
Militar getMeuDono() {
return
meuDono;
}
}
Conforme definido, este objeto possui um
atributo meuDono que representa uma referência para um tipo
Militar. Este atributo foi definido com a anotação @ManyToOne,
de funcionamento similar ao exemplo tratado neste estudo. Vamos ao código de
teste TestDriver.java:
package
engine;
import
model.manytoone.*;
import
dao.AbstractDAO;
public
class TestDriver
{
public
static
void main(String
args[]) {
PostoGraduacao
grad = new
PostoGraduacao();
grad.setDescricao(
"2º Tenente"
);
Militar
mil1 = new
Militar();
mil1.setNome(
"Guilherme"
);
mil1.setPostoGraduacao( grad
);
Documento
doc1 = new
Documento();
doc1.setDescricao(
"CPF" );
doc1.setMeuDono( mil1
);
Documento
doc2 = new
Documento();
doc2.setDescricao(
"Identidade"
);
doc2.setMeuDono(
mil1 );
Militar
mil2 = new
Militar();
mil2.setNome(
"João" );
mil2.setPostoGraduacao( grad
);
AbstractDAO.getInstance().create(
grad );
AbstractDAO.getInstance().create(
mil1 );
AbstractDAO.getInstance().create(
mil2 );
AbstractDAO.getInstance().create(
doc1 );
AbstractDAO.getInstance().create(
doc2 );
}
}
Após executarmos esse programa, o
resultado encontrado no MySQL será:

Conforme esperado, a tabela
documentos possui um campo militar_id utilizado como chave
estrangeira para o campo id (chave primária) da tabela
militar.
Relacionamento @OneToMany
unidirecional
Vamos agora ao entendimento do
relacionamento @OneToMany unidirecional. Este é um caso típico onde um
objeto qualquer possua uma coleção de outros objetos, sendo que, o objeto
um da relação conhece sua coleção, porém nenhum dos objetos muitos
precisa saber a qual objetos estão relacionados. Veja um exemplo
abaixo:

Neste caso, o objeto Militar
possui uma coleção de telefones e precisa conhecer cada um deles. Já o
objeto Telefone não conhece com qual objeto está relacionado. Neste
caso, vamos utilizar apenas a anotação @OneToMany no lado do objeto
Militar.
Veja abaixo o código de
Telefone.java:
package
model.manytoone;
import
java.io.Serializable;
import
javax.persistence.Entity;
import
javax.persistence.Table;
import
javax.persistence.Id;
import
javax.persistence.GeneratedValue;
import
javax.persistence.Column;
@Entity(
name = "Telefone"
)
@Table(
name = "telefones"
)
public
class Telefone
implements
Serializable {
private
static
final
long
serialVersionUID
= 7451235917815653206L;
@Id
@GeneratedValue
@Column(
name = "id"
)
private
Long
id;
@Column(
name = "numero" ,
nullable = false
)
private
String
numero;
public
Long getId() {
return
id;
}
public
void setId(Long
id) {
this.id
= id;
}
public
String getNumero() {
return
numero;
}
public
void
setNumero(String numero) {
this.numero
= numero;
}
}
Este arquivo é simples. Veremos agora o
arquivo Militar.java que mais uma vez foi modificado.
package
model.manytoone;
import
java.io.Serializable;
import
java.util.List;
import
javax.persistence.Entity;
import
javax.persistence.Table;
import
javax.persistence.Id;
import
javax.persistence.GeneratedValue;
import
javax.persistence.Column;
import
javax.persistence.ManyToOne;
import
javax.persistence.OneToMany;
import
javax.persistence.JoinColumn;
@Entity(
name = "Militar"
)
@Table(
name = "militares"
)
public
class Militar
implements
Serializable {
private
static
final
long
serialVersionUID
= 2485833714032900145L;
@Id
@GeneratedValue
@Column(
name = "id"
)
private
Long
id;
@Column(
name = "nome"
)
private
String
nome;
@ManyToOne(
optional = false
)
@JoinColumn(
name =
"postograduacao_id" ,
referencedColumnName =
"id"
)
private
PostoGraduacao
postoGraduacao;
@OneToMany(
mappedBy = "meuDono"
)
private
List<Documento>
documentos;
@OneToMany
private
List<Telefone>
telefones;
public
Long getId() {
return
id;
}
public
void setId(Long
id) {
this.id
= id;
}
public
String getNome() {
return
nome;
}
public
void
setNome(String nome) {
this.nome
= nome;
}
public
PostoGraduacao getPostoGraduacao() {
return
postoGraduacao;
}
public
void
setPostoGraduacao(PostoGraduacao postoGraduacao)
{
this.postoGraduacao
= postoGraduacao;
}
public
void
setDocumentos(List<Documento> documentos)
{
this.documentos
= documentos;
}
public
List<Documento> getDocumentos() {
return
documentos;
}
public
void
setTelefones(List<Telefone> telefones)
{
this.telefones
= telefones;
}
public
List<Telefone> getTelefones() {
return
telefones;
}
}
Observe que neste caso, a anotação
@OneToMany do atributo telefones não possui nenhum parâmetro
informativo. Abaixo, temos o arquivo de teste TestDriver.java:
package
engine;
import
java.util.ArrayList;
import
java.util.List;
import
model.manytoone.Documento;
import
model.manytoone.Militar;
import
model.manytoone.PostoGraduacao;
import
model.manytoone.Telefone;
import
dao.AbstractDAO;
public
class TestDriver
{
public
static
void main(String
args[]) {
PostoGraduacao
grad = new
PostoGraduacao();
grad.setDescricao(
"2º Tenente"
);
Militar
mil1 = new
Militar();
mil1.setNome(
"Guilherme"
);
mil1.setPostoGraduacao( grad
);
Telefone
tel1 = new
Telefone();
tel1.setNumero(
"(11) 1111-1111"
);
Telefone
tel2 = new
Telefone();
tel2.setNumero(
"(22) 2222-2222"
);
List<Telefone>
telefones = new
ArrayList<Telefone>();
telefones.add( tel1 );
telefones.add( tel2 );
mil1.setTelefones( telefones
);
Documento
doc1 = new
Documento();
doc1.setDescricao(
"CPF" );
doc1.setMeuDono( mil1
);
Documento
doc2 = new
Documento();
doc2.setDescricao(
"Identidade"
);
doc2.setMeuDono( mil1 );
Militar
mil2 = new
Militar();
mil2.setNome(
"João" );
mil2.setPostoGraduacao( grad
);
AbstractDAO.getInstance().create(
tel1 );
AbstractDAO.getInstance().create(
tel2 );
AbstractDAO.getInstance().create(
grad );
AbstractDAO.getInstance().create(
mil1 );
AbstractDAO.getInstance().create(
mil2 );
AbstractDAO.getInstance().create(
doc1 );
AbstractDAO.getInstance().create(
doc2 );
}
}
Após executarmos este arquivo, o
seguinte resultado será encontrado:

Este é um caso interessante. Veja que o
JPA gerou, além das tabelas associadas às entidades Telefone e
Militar, uma outra tabela chamada militares_telefones. Isso
ocorre pelo fato de que, na prática, para armazenar vários telefones na tabela
militares, teriam que existir dados duplicados (militar de código 1 com
telefone de código 1, militar de código 1 com telefone de código 2). Isso
faria com que o banco ficasse desnormalizado (fora das formas normais). Por
isso o próprio framework criou uma tabela associativa para relacionar essas
tabelas. Podemos especificar os dados dessa tabela explicitamente com a
anotação @JoinTable.
@OneToMany
@JoinTable(
name
= "agenda_telefones" ,
joinColumns=@JoinColumn(
name = "militar_id" ) ,
inverseJoinColumns=@JoinColumn(
name = "telefone_id" ))
private
List<Telefone>
telefones;
Desta forma, a tabela de associação
entre os elementos seria chamada de agenda_telefones, o campo
relacionado à tabela militares seria militar_id e o campo
relacionado à tabela telefones seria telefone_id.
Relacionamento @OneToMany
bidirecional
Este caso é similar ao caso do
relacionamento @ManyToOne bidirecional, só que deve ser entendido do lado
um. Seria o caso de colocar o problema sob outra perspectiva. Por
exemplo, o objeto Militar possui muitos objetos Documento, sendo
que cada um desses documentos conheçam o outro lado do relacionamento (no
caso, o Militar). O código para geração deste estudo é exatamente igual
ao código mostrado no caso @ManyToOne de
Militar/Documento.
Conclusões
Deve-se sempre priorizar a necessidade
do modelo na escolha do tipo de relacionamento, lembrando também do tipo de
relacionamento que será criado no banco. Ao optar em manter uma forte
confiabilidade e integridade no banco de dados, talvez sejam necessárias
alterações nos relacionamentos do modelo. Por exemplo, um relacionamento
@OneToMany unidirecional entre dois objetos no qual o lado muitos
não pode conhecer os elementos do lado um implicariam na criação de
uma terceira tabela apenas para manter os relacionamentos no banco (como no
exemplo mostrado em @OneToMany unidirecional). Porém, essa tabela, de
fato, poderia ser suprimida com um relacionamento simples de chave
estrangeira.
Este estudo concentrou-se na
implementação do modelo abaixo:

Revisando o entendimento dos
relacionamentos, temos os seguintes detalhes:
-
O objeto Militar possui um relacionamento com PostoGraduacao, sendo que, Militar precisa conhecer o relacionamento e PostoGraduacao não. Por isso Militar possui um atributo PostoGraduacao qualificado pela anotação @ManyToOne
-
Militar possui uma coleção de objetos Documento e cada objeto Documento está associado com um único Militar. Deve ser considerado que neste caso, ambos objetos precisam conhecer o outro lado do relacionamento. Por conseqüência, Militar possui um atributo List<Documento> definido com uma anotação @OneToMany e Documento possui um atributo Militar definido com @ManyToOne. Neste caso temos o relacionamento bidirecional.
-
Por fim, o objeto Militar possui uma coleção de objetos Telefone e cada Telefone pertence a um único Militar. Neste caso, Telefone não precisa conhecer a qual objeto Militar ele pertence, porém o objeto Militar precisa conhecer todos seus objetos Telefone. Desta forma, Militar possui um atributo List<Telefone> qualificado com as anotações @OneToMany e @JoinTable, respectivamente, usadas para definir o tipo de associação e para identificar a tabela associativa entre as tabelas geradas.
Observado os detalhes da modelagem,
através da geração automática, conquistou-se o seguinte modelo E/R (Modelo de
Entidade e Relacionamento):

Cabe a equipe de projeto analisar cada
situação de forma particular, considerando que as formatações escolhidas para
as anotações JPA terão diferentes conseqüências no padrão de geração das
tabelas no banco de dados.
Download do Projeto (código fonte)
Você poderá realizar o download deste projeto, desenvolvido no Eclipse,
através do link abaixo.
Referências
http://rfiume.blogspot.com/2007/04/relacionamento-one-to-many-e-many-to.html
http://www.slideshare.net/cmilfont/course-hibernate-2008-presentation
Porquê aderir a Marinha se você pode ser um pirata?
- Steven Jobs
Espero ter ajudado!
Guilherme Pontes
Nenhum comentário:
Postar um comentário