Mapeamento Objeto-‐
Relacional com
Hibernate
Sistemas de Informação
Prof. Vinicius Cardoso Garcia
vcg@cin.ufpe.br
Licença do Material
Este Trabalho foi licenciado com uma
Licença
CreaIve Commons -‐
Atribuição-‐NãoComercial-‐
ComparIlhaIgual 3.0 Não Adaptada
.
Mais informações visite
Referências
• Notas de aula baseadas no material do curso:
– Mapeamento Objeto/Relacional com Hibernate, Tutorial Básico,
ESJUG: Grupo de Usuários Java do Espírito Santo
• Chris>an Bauer, Gavin King. Java Persistence with Hibernate (Edição revisada do livro Hibernate in Ac>on)
– h:p://jpwh.org/
• h:p://www.hibernate.org/
– Documentação e Javadoc
– Fórum de discuções e dúvidas
• JSR 220: Enterprise JavaBeans Version 3.0
– Para as Annota>ons do pacote javax.persistence
• GOODWILL, James. Mastering Jakarta Struts, Wiley, 2002
• Paul Deitel e Harvey Deitel. Java -‐ Como Programar -‐ 8ª Edição. Pren>ce Hall -‐ Br, 2010.
LogísIca
• Apresentação do professor
• Material
• Dúvidas? Interrompam a
vontade...
• Celulares silenciosos
• Exercício
ObjeIvos
•
Ao final desta aula, o estudante será capaz de:
–
Aprender sobre mapeamento objeto/
relacional, uma nova forma de realizar
persistência;
–
Conhecer os conceitos básicos do
framework Hibernate;
–
Capacitar os alunos na construção de
sistemas de informação u>lizando
O Que veremos?
•
Persistência
•
Paradigma OO/Relacional
•
Hibernate
•
Mapeando Componentes
•
Mapeando Herança
•
Mapeando coleções
•
Associação entre En>dades
•
Ciclo de Vida dos Objetos
O que é persistência?
•
É um tópico vital para o desenvolvimento
de aplicações
•
Quase todas as aplicações necessitam que
dados sejam persis>dos
•
Necessidades
–
Armazenamento
–
Busca
–
Organização
Persistência
•
Necessidades
–
Integridade dos dados
–
Controle de concorrência
•
Performance e a escalabilidade são
fortemente afetadas pela estratégia
de acesso a dados escolhida
Banco de Dados Relacionais
•
Geralmente são u>lizados banco de
dados SQL
– Flexível
– Robusto
– Eficiente
–
Confiável
–
Maneira mais u>lizada e conhecida de
armazenar dados
Banco de Dados Relacionais
•
Dados são armazenados de forma
independente
–
Independência de linguagem
–
Independência de aplicação
•
Os dados geralmente possuem longevidade
maior do que as aplicações que os acessam
•
A u>lização de algum framework não
elimina a necessidade de conhecimento de
SQL e do modelo relacional
PersisIndo dados com Java
•
Realizado através da API Java Database
Connec>vity (JDBC)
•
Tarefas de baixo nível
–
Preparar consultas
–
Associar parâmetros
–
Executar a consulta
–
Percorrer e retornar o resultado
•
Tarefas de alto nível
PersisIndo dados com Java
•
Linguagem orientada a objetos
•
Deve-‐se poder armazenar o estado de um
objeto, mesmo após o objeto ser destruído
•
Deve ser possível criar um novo objeto com
o mesmo estado do anterior
•
Operações não devem ser limitadas a um
único objeto
PersisIndo objetos com Java
•
A aplicação deve trabalhar diretamente
com objetos, ao invés de linhas e colunas
da base de dados
•
Lógica de negócio deve ser implementada
na aplicação, u>lizando-‐se Java, e não
diretamente na base de dados
–
Limitar o uso de stored procedures
•
Conceitos da Orientação a Objetos não
devem ser restringidos pela solução
Diferença dos Paradigmas: OO/
Relacional
•
Granularidade
–
Objetos de baixa granularidade podem ser
persis>dos em tabelas de grande
granularidade ou vice-‐versa
• Uma tabela armazena diversos >pos de objetos • Um objeto é armazenado em diversas tabelas
•
Herança
–
Modelo relacional não possui o conceito de
herança
Diferença dos Paradigmas: OO/
Relacional
•
Polimorfismo
–
Necessidade de um objeto referenciar
outros através de superclasses
–
Uma referência pode estar associada o
objetos de >pos diferentes
–
Chaves estrangeiras referenciam uma
tabela específica
Diferença dos Paradigmas: OO/
Relacional
•
Iden>dade dos objetos
– Java
•
Operador ==
•
Método equals()
– Banco de dados
•
Chave primária
•
Atualização de algum atributo que faz parte
da chave requer que outras tabelas sejam
atualizadas
Diferença dos Paradigmas: OO/
Relacional
• Associações
– OO possui associações unidirecionais e bidirecionais
– Junções de tabelas e projeções não possuem o conceito de “direção” de uma associação
– Associações em OO podem ser do >po many-‐to-‐many – Associações entre tabelas só podem ser one-‐to-‐many e
one-‐to-‐one
• Necessidade de criar uma tabela de relacionamento para associações many-‐to-‐many
Diferença dos Paradigmas:
Custo
•
Necessário escrever muito código para (tentar)
contornar o problema
•
Código se torna repe>>vo e de dixcil
manutenção
•
A escrita de código SQL pode tornar a aplicação
dependente do banco de dados
•
Modelagem dos objetos fica prejudicada
•
Outras camada ficam fortemente acopladas à
Camada de Persistência
Estratégias de Persistência
•
JDBC e SQL
– Faz parte da plataforma Java
– Necessário escrever bastante código de
baixo nível
•
Stored Procedures
– Lógica de negócio sai da aplicação e vai
para a base de dados
Estratégias de Persistência
•
Framework corpora>vo
–
Necessário grande esforço da empresa
–
Demora-‐se muito para que a solução
implementada a>nga maturidade
–
Documentação muitas vezes é
esquecida
Estratégias de Persistência
•
Java Persistence API (JPA)
– Especificação elaborada pelo Java Community Process para persistência em Java
– Baseou-‐se em diversas soluções existentes
– Frameworks existentes passaram a implementar a especificação
– Recursos são um sub-‐conjunto dos encontrados nos frameworks que a implementam
Estratégias de Persistência
•
Frameworks de terceiros
–
TopLink
•
Framework de persistência Objeto/
Relacional
•
Desenvolvido pela Oracle
•
Gratuito para avaliação e nas fases de
desenvolvimento
Hibernate
•
Framework de mapeamento Objeto-‐Relacional
•
Preenche a lacuna entre a base de dados
relacional e a aplicação orientada a objetos
•
Framework de persistência Java mais u>lizado e
documentado
•
Man>do pela Jboss sob a licensa LGPL
•
Suporta classes desenvolvidas com agregação,
herança, polimorfismo, composição e coleções
Hibernate
•
Permite a escrita de consultas tanto através de
uma linguagem própria (HQL) como também
através de SQL
•
Framework não intrusivo
– Não restringe a arquitetura da aplicação
•
Implementa a especificação Java Persistence
API
•
Grande e a>va comunidade
l Mais de 25 mil desenvolvedores registrados nos
Mapeamento Objeto
Relacional
•
Permite a persistência de objetos em
tabelas de uma base de dados relacional
•
Automá>ca e Transparente
•
U>liza metadados para descrever o
relacionamento entre os objetos e a base
de dados
l
XML
l
Xdoclet
Mapeamento Objeto
Relacional
•
O SQL é gerado automa>camente a par>r dos
metadados
•
A escrita e manutenção de metadados
necessita de esforço nas etapas de
implementação
– Esforço bem menor do que o necessário para fazer a conversão manualmente
•
A conversão entre os >pos de representação
pode trazer perca de performance
– Ferramentas maduras o>mizam a conversão em diversos pontos
Mapeamento Objeto
Relacional
•
Possui quatro partes principais
–
API para realização de operações básicas
(CRUD)
–
Linguagem ou API para a realização de
consultas
–
Maneira para a especificação de metadados
–
Técnicas de o>mização
• Dirty checking
Mapeamento Objeto
Relacional: Vantagens
•
Produ>vidade
– Elimina a necessidade de escrita de grande parte do código rela>vo a persistência
l Maior tempo disponível para implementar a lógica
da aplicação
•
Manutenibilidade
– Menos código
– Maior entendimento da aplicação – Camada de abstração
Mapeamento Objeto
Relacional: Vantagens
• Performance
– Tarefas manuais nem sempre tem performance melhor do que tarefas automa>zadas
• Considerando limitações de custo e tempo
– Frameworks maduros são bastantes o>mizados
– Com o aumento de produ>vidade, você pode dedicar mais tempo para resolver possíveis gargalos
• Portabilidade
l Independência nem sempre é algo simples de ser
alcançado, mesmo em aplicações Java
Mapeamento Objeto Relacional
Estrutura OO
Estrutura Relacional
Classe (En>dade)
Tabela
Objeto
Linha
Atributo
Coluna
Método
-‐
Mapeamento Objeto
Relacional: Dificuldades
• O modelo de representação dos dados em um banco relacional não é compa{vel com a representação
direta de uma hierarquia de objetos
– Não há herança
– Não há polimorfismo
• Os >pos de dados u>lizados em uma linguagem orientada a objetos não são os mesmos existentes em um banco de dados;
• É necessário transformar os objetos para tabelas e as tabelas para objetos novamente;
Mapeamento Objeto
Relacional
• JDBC (Java Database Connec>vity)
– API do Java para acesso a banco de dados relacionais – Para cada Banco de dados há um driver JDBC
– Com o Driver obtemos conexões – Com conexões enviamos comandos
– Comandos podem gerar resultados (select)
• Uso {pico h:p://www.cin.ufpe.br/~if992 32 !"#$"%$&'()*+,$'(-.$/"01(&"/)2*.!3 4567)24"8")5"'"+"9$)7(&&$0'181':3 ! ;<=)>()4"8")#"?")"0$99()")+"&0()>$)>">(9)?$/"01(&"19 ! <"?")0">")6"&0()>$)>">(9)@A)B%)>?18$?)4567 ! 7(%)()5?18$?)(+'$%(9)0(&$CD$9 ! 7(%)0(&$CD$9)$&81"%(9)0(%"&>(9 ! 7(%"&>(9)#(>$%)E$?"?)?$9B/'">(9)29$/$0'3 F9()'G#10() !!"#$$%&#'"(#))%'*+'*$,-%$ .(#))/0+$1#2%'34+$#"(%/5*6"/*$,-%$/7$#"(%8$,-%$49: !!"+;%"<#'#+'6#;"+'*%'*#*+) .+;;%"<,+;'"+;'='8$,-%$>#;#&%$/&%<.+;;%"<,+;3 45*6"?+$#"(%?<@,;?A2B7$#"(%C+)<?DEFD?2B8G4H4I)%$4H4J#))49: !!"$,#'%'%K%"I<#'I2'LMNM.O L<#<%2%;<')<2<'='"+;/"$%#<%L<#<%2%;<39: P%)I(<L%<'$)'=')<2</%K%"I<%QI%$B34LMNM.O')#(*+'RP7>'O6.+;<#49:
Mapeamento Objeto
Relacional
• Novas estratégias de mapeamento
– En>ty Beans 1.x, 2.0, 2.1 e 3.0 (padrão Java EE -‐ EJB) – Hibernate
– Oracle TopLink
– Java Data Objects (JDO) – Castor
• Grande parte das abordagens trocam SQL por metadados XML
Vantagens de Hibernate
sobre JDBC
•
Persistência transparente: mapeamento
automá>co de objetos Java para estrutura
relacional em tabelas do banco de dados.
Implementa mecanismos de mapeamento:
– Classes Java ↔ Tabelas em SGBDs relacionais – Tipos Java ↔ Tipos SQL
•
Linguagem de consulta – Hibernate Query
Language (HQL)
– Semân>ca OO: polimorfismo, etc – Independente de banco de dados
Vantagens de Hibernate
sobre JDBC
•
Código dependente de banco de
dados é reduzido
–
Uma mudança no banco requer
somente ajustes em arquivos XML
•
Custo de manutenção é reduzido
–
Menos linhas de código são escritas
para mapeamento objeto-‐ tabela
Desvantagens do Hibernate
• Necessidade de aprendizado da tecnologia;• Hibernate cria um overhead (nova camada de abstração) e aumenta complexidade em aplicações que:
– são simples
– usam um banco de dados que nunca muda;
• Para dados complexos, mapeamento entre objetos e tabela pode reduzir performance e aumentar tempo de
conversação com SGBD;
• Hibernate não permite alguns >pos de comandos suportadas com JDBC.
Por que usar Hibernate?
• Hibernate, em teoria, reduz 95% do tempo de desenvolvimento de tarefas relacionadas à
persistência; • Custo
– é opensource LGPL;
• Benexcio
– é uma solução poderosa, madura e portável compa{vel com diversos bancos de dados relacionais e servidores de aplicação Java EE;
• Curva de aprendizado
Por que usar Hibernate?
• Documentação
– livros publicados e diversos tutoriais e ar>gos disponíveis na internet;
• Suporte
– pode ser contratado comercialmente ou pode se recorrer a uma comunidade extremamente a>va nos fóruns de
discussão;
• Padrão “De Facto”
– amplamente adotado pelo mercado;
• Os conceitos do projeto Hibernate foram adotados para os en>ty beans segundo a especificação EJB 3;
Hibernate: Módulos
•
Hibernate Core
– Contém os serviços básicos – Metadados escritos em XML – Consultas
• HQL: Hibernate Query Language
• Interfaces u>lizando critérios e exemplos
– Não depende de outros módulos
– Não depende de uma versão específica do JDK – Executável em qualquer servidor Web e/ou de
Hibernate: Módulos
•
Hibernate Annota>ons
– Permite a escrita de metadados através de Annota>ons
– Beneficia-‐se da >pagem do Java
– Compa{vel com refatorações de código
– Semân>ca familiar para quem já está acostumado com metadados em XML
– U>liza as Annota>ons da especificação JPA
– Possui Annota>ons próprias para configurações avançadas não presentes na especificação
Hibernate: Módulos
•
Hibernate En>ty Manager
– Implementação da especificação JPA
– Permite a escrita de código compa{vel
com qualquer framework de persistência
que implemente a especificação
–
U>liza o pacote javax.persistence
– Não disponibiliza todas as funcionalidades
do Hibernate
Separação em camadas
•
É uma boa prá>ca dividir aplicações de
médio e grande porte em camadas
– Padrão Layers (Pa:ern-‐Oriented So•ware
architecture)
•
Divisão mais u>lizada
– Apresentação
– Negócio
Separação em camadas
•
Permite a especificação de intefaces para os
diversos >pos de serviços
– A implementação pode ser mudada sem afetar significa>vamente o código de outras camadas
•
A comunicação ocorre das camadas superiores
para as camadas inferiores
•
Uma camada só depende da camada
imediatamente inferior
– Camada de apresentação não sabe da existência da camada de persistência
Download e instalação
•
Arquivos necessários:
– Distribuição do Hibernate (www.hibernate.org); – Hibernate Annota>ons (idem);
– Banco de dados HSQLDB (www.hsqldb.org).
•
U>lização da IDE Eclipse:
– O plugin Hibernate Tools facilita muito o trabalho;
•
Adição das bibliotecas necessárias no Build Path
do Eclipse (diretório lib).
Bibliotecas necessárias
•
antlr: ANother Tool for Language Recogni>on;
•
asm-‐a:rs: ASM bytecode library;
•
asm: ASM bytecode library;
•
c3p0: pool de conexões JDBC;
•
cglib: gerador de bytecodes;
•
commons-‐collec>on: Commons Collec>on;
•
commons-‐logging: Commons Logging;
•
dom4j: parser da configuração e mapeamentos;
•
ehcache: provedor de cache;
Bibliotecas necessárias
•
hibernate3: Hibernate 3;
•
hsqldb: banco de dados HSQLDB;
•
jaxen: opcional, usado para desserialização da
configuração (aumento de desempenho);
•
jdbc2_0-‐stdext: Standard Extension JDBC APIs
(obrigatório fora de um Applica>on Server);
•
jta: Standard JTA API (idem);
•
log4j: ferramenta de log;
•
ejb3-‐persistence e hibernate-‐annota>ons:
Hibernate Annota>ons.
Criando uma enIdade
@Entity@Table(name = "MESSAGES")
public class Message {
@Id
@GeneratedValue
@Column(name = "MESSAGE_ID")
private Long id;
@Column(name = "MESSAGE_TEXT")
private String text;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "NEXT_MESSAGE_ID")
private Message nextMessage;
private Message() {}
public Message(String text) {
this.text = text; }
AnnotaIons da classe
•
En>ty
–
Informa que a classe pode ser persis>da
pelo Hibernate
•
Table
–
Informa o nome da tabela em que os
objetos da classe devem ser armazenados
@Entity
@Table(name = "MESSAGES")
Construtores
•
Obrigatório um construtor sem
argumentos
private Message() {}
public Message(String text) {
Propriedades
•
Representa o iden>ficador do objeto
•
Preenchido automa>camente quando o
objeto é salvo
•
Mapeado para a chave primária da tabela
•
Se duas instâncias >verem o mesmo
iden>ficador, elas representam a mesma
linha da tabela
@Id
@GeneratedValue
@Column(name = "MESSAGE_ID")
Atributos
•
O atributo text é armazenado na
coluna MESSAGE_TEXT
@Column(name = "MESSAGE_TEXT")
private String text;
•
O atributo nextMessage é uma associação
many-‐to-‐one
•
Mapeado pela chave estrangeira
NEXT_MESSAGE_ID
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "NEXT_MESSAGE_ID")
Transparência
•
Não há a necessidade de se herdar de uma
superclasse ou de implementar um interface
– POJO -‐ Plain Ordinary Java Objects
•
Classes podem ser reu>lizadas fora do contexto
de persistência
– Interface com o usuário – Testes de unidades
•
As en>dades não precisam nem saber que
serão persis>das
Arquitetura (visão alto nível)
• Hibernate usa o banco de dados e dados de
configuração para fornecer serviços de persistência para a aplicação;
• hibernate.properIes ou hibernate.cfg.xml
– se ambos esIverem presentes o segundo
sobrescreve propriedades descritas no primeiro;
!"#$%&'&$"()*+%,-.)(/&.)01+'/2
3%4'"0(&')$,().)4(05.)6')6(6.,)') 6(6.,)6')5.07%8$"(9-.):("()7."0'5'") ,'"+%9.,)6'):'",%,&;05%():("()() (:/%5(9-.< =%4'"0(&'>:".:'"&%',).$) =%4'"0(&'>578>?@/) ! ,')(@4.,)',&%+'"'@):"','0&',).) ,'8$06.),.4"'',5"'+'):".:"%'6(6',) 6',5"%&(,)0.):"%@'%".< h:p://www.cin.ufpe.br/~if992 54Arquitetura
• Hibernate usa diversas APIs para fornecer serviço de persistência;
• Opcionais
– JNDI (Java Naming and Directory Interface): datasource configurado no servidor da aplicação;
– JTA (Java TransacIon API): uso de transações distribuídas ;
!"#$%&'&$"(
)%*'"+(&',$-(,.%/'"-(-,!01-, 2("(,34"+'5'",-'"/%64,.', 2'"-%-&7+5%(8 925%4+(%-! :;<1,=:(/(,;(>%+?,(+., <%"'5&4"@,1+&'"3(5'AB, .(&(-4$"5',54+3%?$"(.4,+4, -'"/%.4",.(,(2C%5(6D48 ! :E!,=:(/(,E"(+-(5&%4+,!01AB, $-4,.',&"(+-(6F'-, .%-&"%*$G.(-,8 h:p://www.cin.ufpe.br/~if992 55Configurando o Hibernate
•
Configuração feita através do arquivo
hibernate.cfg.xml
•
Deve estar localizado na raiz do classpath
– Localização default
– Para projetos maven, u>lizar a pasta src/main/ resources
•
Configurações contém
– Parâmetros de acesso a base de dados – Pool de conexões
hibernate.cfg.xml
<hibernate-configuration> <session-factory>
<!-- Parâmetros de acesso a base de dados --> <property name="connection.driver_class">
org.postgresql.Driver
</property>
<property name="connection.url">
jdbc:postgresql://localhost:5432/if992
</property>
<property name="connection.username"> postgresql
</property>
<property name="connection.password"> postgresql
</property>
<property name="dialect">
org.hibernate.dialect.PostgreSQLDialect
hibernate.cfg.xml
...
<!-- Configuração do Pool de conexões -->
<property name="c3p0.min_size">5</property> <property name="c3p0.max_size">20</property> <property name="c3p0.timeout">300</property>
<property name="c3p0.max_statements">50</property>
<property name="c3p0.idle_test_period">3000</property>
<!-- Exibe no console o SQL gerado pelo hibernate-->
<property name="show_sql">true</property>
<!-- Cria e executa a DDL (tabelas, colunas, etc...)-->
<property name="hbm2ddl.auto">create</property>
<!-- Informa as Entidades da aplicação -->
<mapping class="br.gov.serpro.curso.hibernate.exemplo1.Message" /> </session-factory>
Armazenando uma Mensagem
//Obtendo o Session
Session session = HibernateUtil.getSessionFactory ().openSession();
//Iniciando a transação
Transaction tx = session.beginTransaction();
// Criando uma mensagem
Message message = new Message("Hello World");
// Salvando a Mensagem
Long msgId = (Long) session.save(message);
//Fazendo o commit da transação
tx.commit();
//Fechando o Session
Objetos uIlizados
•
Session
– Contém métodos u>lizados para armazenar e recuperar en>dades
– Armazena uma lista de comandos SQL que serão executados, em algum momento, na base de
dados
– Mantém as en>dades gerenciadas pelo Hibernate
• Recuperadas, inseridas ou atualizadas através do Session
Objetos uIlizados
•
Transac>on
– U>lizado para delimitar as transações com
a base de dados
–
Geralmente gerenciado pelo container
•
EJB
•
Spring
•
SessionFactory
–
U>lizado para criar os Session
–
Reu>lizável por toda a aplicação
HibernateUIl
public class HibernateUtil {
private static SessionFactory sessionFactory;
static {
sessionFactory = new AnnotationConfiguration() .configure().buildSessionFactory();
}
public static SessionFactory getSessionFactory() {
return sessionFactory; }
public static void shutdown() {
getSessionFactory().close();
} }
Recuperando as Mensagens
Session newSession = HibernateUtil.getSessionFactory().openSession(); Transaction newTransaction = newSession.beginTransaction();
//Criando e executando uma consulta
Query query = newSession
.createQuery("from Message m order by m.text asc"); List<Message> messages = query.list();
//Retornando a quantidade de mensagens encontradas
System.out.println(messages.size() + " message(s) found:");
//Retornando as mensagens encontradas for (Message msg : messages) {
System.out.println(msg.getText()); }
newTransaction.commit(); newSession.close();
Objetos UIlizados
•
Query
–
Cria as consultas
–
Associa os parâmetros
–
Executa as consultas
Dirty Checking e Cascade
Session thirdSession = HibernateUtil.getSessionFactory().openSession(); Transaction thirdTransaction = thirdSession.beginTransaction();
// recuperando a mensagem
message = (Message) thirdSession.get(Message.class, msgId);
//Alterando o texto
message.setText("Greetings Earthling");
//Criando uma nova mensagem e associando à antiga
message.setNextMessage(new Message("Take me to your leader")); thirdTransaction.commit();
thirdSession.close();
Dirty Checking e Cascade
•
Dirty Checking
– O Hibernate automa>camente verifica quando um atributo é modificado
– O atributo é atualizado na base de dados sem a necessidade de uma chamada explicita
– É possível somente dentro de uma transação e para objetos gerenciados pelo Session
•
Cascade
– Novas en>dades são persis>das automa>camente – Devem ser alcançáveis a par>r de uma en>dade
Metadados
•
U>lizados para especificar o mapeamento entre
– Classes e tabelas
– Propriedades e colunas
– Associações e chaves estrangeiras
– Tipos de atributos Java e >pos de atributos SQL
•
Pode ser escrita de duas formas
– Arquivos XML – Xdoclet
Porque não usar XML
•
Pode ser tornar pouco legível e de dixcil
edição
– Requer maior digitação
–
Falta de valores default para atributos e
elementos
•
Não necessariamente mais flexível e
mais fácil de manter do que código Java
•
Mais fácil encontrar um bom editor Java
Metadados com AnnotaIons
•
A meta-‐informação fica perto dos dados que ela
descreve
•
Compa{vel com refatoração de código
– Renomear, deletar e remover classes e propriedades
•
Sem necessidade de fazer parser em XML
– Inicialização mais rápida
•
Lido através de reflec>on na inicialização do
Hibernate
Mapeando Propriedades
•
Ao mapear uma classe através da Annota>on
@En#ty, todas as propriedades serão
consideradas persistentes
•
Propriedades não persistentes devem receber a
Annota>on @Transient ou o modificador
transient
•
Por default, o nome da coluna será o mesmo da
propriedade
•
Meio de acesso é o mesmo do @ID
@Column
•
Aplicável para propriedades simples
•
Atributos
– name
•
Nome da coluna a qual a propriedade é
mapeada
–
unique
•
Se o valor deve ser único ou não
– nullable
Datas
• Propriedades podem ser do >po java.u#l.Date ou
java.u#l.Calendar
• Precisão default é TIMESTAMP
• Precisão pode ser alterada através da Annota#on @Temporal
@Temporal(TemporalType.DATE)
private Date date1;
@Temporal(TemporalType.TIME)
private Date date2;
@Temporal(TemporalType.TIMESTAMP)
IdenIdade das EnIdades
•
Iden>dade versus Equivalência em Java
– Iden>dade
• Operador ==
• Definido pela máquina virtual
• Dois objetos são idên>cos se eles apontam para o mesmo local da memória
– Equivalência
• Definida pelas classes que sobreescrevem o método equals()
• Dois objetos diferentes possuem o mesmo valor
IdenIdade das EnIdades
•
Iden>dade na base de dados
–
Duas En>dades são idên>cas se elas
representam a mesma linha na base de
dados
•
Se são armazenadas na mesma tabela e
possuem a mesma chave primária
Adicionando um IdenIficador
•
O valor é gerado automa>camente pelo
Hibernate
•
Não deve ser mudado pela aplicação
@Entity
@Table(name="CATEGORY")
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "CATEGORY_ID")
private Long id;
Escolhendo a chave primária
•
Uma chave candidata é uma coluna, ou
um conjunto de colunas, que pode ser
u>lizada para iden>ficar um registro na
base de dados
•
Requisitos
–
O valor nunca deve ser nulo
–
Cada registro deve ter um valor único
– O valor nunca deve mudar
Escolhendo a chave primária
•
Chaves naturais são aquelas que
possuem significado para o domínio
da aplicação
–
CPF de um usuário
–
Seqüencial gerado pela aplicação
•
Dificilmente chaves naturais
Escolhendo a chave primária
•
Chaves cegas
–
Melhor alterna>va
–
Não possuem significado para o
domínio da aplicação
–
Geradas pelo banco de dados ou pela
aplicação
Geração automáIca de chaves
•
Hibernate suporta diversas
estratégias para geração automá>ca
de chaves
•
A estratégia deve ser especificada
através da Annota>ons
@GeneratedValue
Estratégias
•
IDENTITY
– Suporte para colunas IDENTITY nos bancos de dados DB2, MySQL, MS SQL Server, Sybase e HypersonicSQL
– Os >pos devem ser long, short ou int
•
SEQUENCE
– U#liza um Sequence para a geração de chaves
– Suporte para DB2, PostgreSQL e Oracle dentre outros
Estratégias
•
increment
–
Na inicialização o Hibernate lê qual o
maior valor para a chave da tabela
–
O valor é atribuído e incrementado em
cada inserção
–
Não deve ser u>lizado se o Hibernate
não >ver acesso exclusivo para a base
de dados
Estratégias
•
AUTO
– Escolhe entre as estratégias IDENTITY, SEQUENCE ou HILO
– Estratégia escolhida depende do banco de dados u>lizado
– U>lizado para manter a portabilidade
•
Outras
– hilo, seqhilo, uuid.hex, guid, select – Iden>fierGenerator
AIvidade
•
Instalação e Configuração do
Hibernate em uma aplicação.
–
if992-‐15-‐Lista_exercicios_9.pdf
•
Criar Classes Persistentes e Testar
–
if992-‐15-‐Lista_exercicios_10.pdf
–
if992-‐15-‐Lista_exercicios_11.pdf
Mapeando Componentes
•
En>dades são classes persistentes que
representam objetos do domínio da aplicação
•
Possuem iden>dade própria
•
Hibernate suporta a construção de um modelo
de objetos de alta granularidade
– Propriedades de uma En>dade podem ser encapsuladas em outros objetos
• Tais objetos não possuem iden>dade própria • Chamados de Objetos Valores ou Componentes
Mapeando Componentes
•
User
– Representa uma En>dade
– Possui iden>dade própria
•
Chave primária na base de dados
–
Uma referência para User é persis>da
como uma chave estrangeira
–
Tem seu próprio ciclo de vida
•
Existe independentemente de qualquer
outra en>dade
Mapeando Componentes
• Address
– Representa um Componente – Não possui iden>dade própria – Pertence a En>dade User
– Estado é persis>do no registro referente ao User a qual está associado
– Ciclo de vida dependente de User
– Se dois Usuários morarem no mesmo apartamento, cada um tem uma referência para um objeto dis>nto – Comportamento similar a >pos como String e Integer
Mapeando Componentes
@Embeddable
public class Address {
@Column(name = "ADDRESS_STREET", nullable = false)
private String street;
@Column(name = "ADDRESS_CITY", nullable = false)
private String city;
//gets e sets...
Mapeando Componentes
@Entity
@Table(name = "USERS")
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
private String email;
private Address address;
//gets e sets
Mapeando Herança
•
A u>lização de uma tabela para cada
en>dade não funciona tão bem para
heranças entre en>dades
•
Bancos de dados SQL, de maneira geral,
não possuem o conceito de herança
–
Soluções proprietária podem
Estratégias
•
Tabela por classe concreta
•
Tabela por classe concreta,
u>lizando junção
•
Tabela por hierarquia
Uma tabela por Classe
Concreta: Modelagem
Uma tabela por Classe Concreta
•
Estratégia mais simples
•
Todas propriedades de uma classe, incluindo as
herdadas, são mapeadas para a mesma tabela
•
Mapeamento convencional pode ser u>lizado
•
Não suporta associações polimórficas
adequadamente
– Associação para classe abstrata necessitaria que a chave estrangeira referenciasse duas tabelas
Uma tabela por Classe Concreta
• Diferentes colunas em diferentes tabelas passariam a possuir a mesma semân>ca
• Recomendável somente para a hierarquia superior – Associações polimórficas geralmente não necessárias e
não recomendadas
– Modificações na superclasse são muito raras
select CREDIT_CARD_ID, OWNER, NUMBER, EXP_MONTH, EXP_YEAR ... from CREDIT_CARD
select BANK_ACCOUNT_ID, OWNER, ACCOUNT, BANKNAME, ... from BANK_ACCOUNT
Mapeando a Superclasse
•
Mapear a super classe através da
Annota†on @MappedSuperclass
@MappedSuperclass
public abstract class BillingDetails {
@Column(name = "OWNER", nullable = false)
private String owner;
//gets e sets...
Mapeando as Subclasses
•
Nenhuma configuração extra é
necessária
@Entity
public class BankAccount extends BillingDetails{ @Id
@GeneratedValue
private Long id;
private Integer account;
private String bank; }
Mapeando as Subclasses
• Mapeamento das propriedades herdadas pode ser alterado
• Adicionar a Annota>on @A:ributeOverride
@Entity
@AttributeOverride(name = "owner", column = @Column(name =
"CC_OWNER", nullable = false))
public class CreditCard extends BillingDetails {
@Id
@GeneratedValue
private Long id;
Uma tabela por Classe
Concreta: Union
•
Com a u>lização de consultas com
Union, alguns problemas podem ser
eliminados
•
Suporte a associações polimórficas
–
Hibernate u>liza o Union para simular
uma única tabela
•
As subclasses herdam o Id da super-‐
classe
Mapeando a Super Classe
•
É u>lizada a Annota>on @Inheritance
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class BillingDetails { @Id @GeneratedValue
@Column(name = "BILLING_DETAILS_ID")
private Long id = null;
@Column(name = "OWNER", nullable = false)
private String owner; }
Mapeando as Subclasses
•
Não é necessário mapear o iden>ficador
– O Iden>ficador é mapeado na super-‐classe
@Entity
public class CreditCard extends BillingDetails{ @Column(name = "CC_NUMBER")
private String number; }
Tabela por Hierarquia
•
Toda uma hierarquia é mapeada em uma
única tabela
•
A tabela possui colunas para todas as
propriedades de todas as en>dades da
hierarquia
•
A subclasse de cada registro é iden>ficada
através de uma coluna discriminatória
•
Vantagem
Tabela por Hierarquia
•
Desvantagens
–
Valores para colunas das subclasses
devem sempre permi>r NULL
•
Perda da restrição NOT NULL
Mapeando a Superclasse
• O valor do atributo strategy deve ser mudado para InheritanceType.SINGLE_TABLE
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class BillingDetails { @Id @GeneratedValue
@Column(name = "BILLING_DETAILS_ID")
private Long id = null;
@Column(name = "OWNER", nullable = false)
private String owner; }
Tabela por classe
•
Uma tabela para todas as classes,
incluindo as abstratas, que possuem
propriedades para serem persis>das
•
Relação de herança é representada por
uma chave estrangeira
•
As tabelas não contém colunas para as
propriedades herdadas
•
A chave primária é também uma chave
estrangeira para a super classe
Tabela por classe
•
Vantagens
–
Os dados são normalizados
–
Restrições podem ser man>das
•
Desvantagens
–
Performance pode ser muito baixa
para hierarquias complexas
Mapeando a Superclasse
• O valor do atributo strategy deve ser mudado para InheritanceType.JOINED
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class BillingDetails { @Id @GeneratedValue
@Column(name = "BILLING_DETAILS_ID")
private Long id = null;
@Column(name = "OWNER", nullable = false)
private String owner; }
Mapeando as Subclasses
•
Id é mapeado na super-‐classe
@Entity
public class CreditCard extends BillingDetails{
@Column(name = "CC_NUMBER")
private String number;
Escolhendo a melhor estratégia
•
Tabela por classe concreta, u>lizando junção
– Se associações ou consultas polimórficas nunca ou raramente são u>lizadas
•
Tabela por hierarquia
– Se associações ou consultas polimórficas são u>lizadas e
– Se as subclasses declaram poucas propriedades
• Maior diferença entre as subclasses é o comportamento