Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Curso De Hibernate 3

16,066 views

Published on

Published in: Technology
  • DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download Full EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download EPUB Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... Download doc Ebook here { https://tinyurl.com/yyxo9sk7 } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • What foods help burn belly fat? ➤➤ https://tinyurl.com/y6qaaou7
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Amigo bom dia! você tem alguma apostila de Spring da SERPRO?
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • interessante...
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Muito bom... bem explicado.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Curso De Hibernate 3

  1. 1. Curso: Persistência em Java com Hibernate <ul><ul><li>Instrutor: Fabrício Lemos </li></ul></ul>23/04/2007
  2. 2. Persistência <ul><li>É um tópico vital para o desenvolvimento de aplicações </li></ul><ul><li>Quase todas as aplicações necessitam que dados sejam persistidos </li></ul><ul><li>Necessidades </li></ul><ul><ul><li>Armazenamento </li></ul></ul><ul><ul><li>Busca </li></ul></ul><ul><ul><li>Organização </li></ul></ul><ul><ul><li>Compartilhamento dos dados </li></ul></ul>
  3. 3. Persistência <ul><li>Necessidades </li></ul><ul><ul><li>Integridade dos dados </li></ul></ul><ul><ul><li>Controle de concorrência </li></ul></ul><ul><li>Performance e a escalabilidade são fortemente afetadas pela estratégia de acesso a dados escolhida </li></ul>
  4. 4. Banco de Dados Relacionais <ul><li>Geralmente são utilizados banco de dados SQL </li></ul><ul><ul><li>Flexível </li></ul></ul><ul><ul><li>Robusto </li></ul></ul><ul><ul><li>Eficiente </li></ul></ul><ul><ul><li>Confiável </li></ul></ul><ul><ul><li>Maneira mais utilizada e conhecida de armazenar dados </li></ul></ul>
  5. 5. Banco de Dados Relacionais <ul><li>Dados são armazenados de forma independente </li></ul><ul><ul><li>Independência de linguagem </li></ul></ul><ul><ul><li>Independência de aplicação </li></ul></ul><ul><li>Os dados geralmente possuem longevidade maior do que as aplicações que os acessam </li></ul><ul><li>A utilização de algum framework não elimina a necessidade de conhecimento de SQL e do modelo relacional </li></ul>
  6. 6. Persistindo dados com Java <ul><li>Realizado através da API Java Database Connectivity (JDBC) </li></ul><ul><li>Tarefas de baixo nível </li></ul><ul><ul><li>Preparar consultas </li></ul></ul><ul><ul><li>Associar parâmetros </li></ul></ul><ul><ul><li>Executar a consulta </li></ul></ul><ul><ul><li>Percorrer e retornar o resultado </li></ul></ul><ul><li>Tarefas de alto nível </li></ul><ul><ul><li>Salvar e recuperar objetos </li></ul></ul>
  7. 7. Persistindo objetos com Java (ou qualquer outra linguagem OO) <ul><li>Linguagem orientada a objetos </li></ul><ul><li>Deve-se poder armazenar o estado de um objeto, mesmo após o objeto ser destruído </li></ul><ul><li>Deve ser possível criar um novo objeto com o mesmo estado do anterior </li></ul><ul><li>Operações não devem ser limitadas a um único objeto </li></ul><ul><ul><li>Associações devem ser salvas </li></ul></ul>
  8. 8. Persistindo objetos com Java <ul><li>A aplicação deve trabalhar diretamente com objetos, ao invés de linhas e colunas da base de dados </li></ul><ul><li>Lógica de negócio deve ser implementada na aplicação, utilizando-se Java, e não diretamente na base de dados </li></ul><ul><ul><li>Limitar o uso de stored procedures </li></ul></ul><ul><li>Conceitos da Orientação a Objetos não devem ser restringidos pela solução adotada </li></ul>
  9. 9. Diferença dos Paradigmas: OO/Relacional <ul><li>Granularidade </li></ul><ul><ul><li>Objetos de baixa granularidade podem ser persistidos em tabelas de grande granularidade ou vice-versa </li></ul></ul><ul><ul><ul><li>Uma tabela armazena diversos tipos de objetos </li></ul></ul></ul><ul><ul><ul><li>Um objeto é armazenado em diversas tabelas </li></ul></ul></ul><ul><li>Herança </li></ul><ul><ul><li>Modelo relacional não possui o conceito de herança </li></ul></ul>
  10. 10. Diferença dos Paradigmas <ul><li>Polimorfismo </li></ul><ul><ul><li>Necessidade de um objeto referenciar outros através de superclasses </li></ul></ul><ul><ul><li>Uma referência pode estar associada o objetos de tipos diferentes </li></ul></ul><ul><ul><li>Chaves estrangeiras referenciam uma tabela específica </li></ul></ul>
  11. 11. Diferença dos Paradigmas OO/Relacional <ul><li>Identidade dos objetos </li></ul><ul><ul><li>Java </li></ul></ul><ul><ul><ul><li>Operador == </li></ul></ul></ul><ul><ul><ul><li>Método equals() </li></ul></ul></ul><ul><ul><li>Banco de dados </li></ul></ul><ul><ul><ul><li>Chave primária </li></ul></ul></ul><ul><ul><ul><li>Atualização de algum atributo que faz parte da chave requer que outras tabelas sejam atualizadas </li></ul></ul></ul>
  12. 12. Diferença dos Paradigmas OO/Relacional <ul><li>Associações </li></ul><ul><ul><li>OO possui associações unidirecionais e bidirecionais </li></ul></ul><ul><ul><li>Junções de tabelas e projeções não possuem o conceito de “direção” de uma associação </li></ul></ul><ul><ul><li>Associações em OO podem ser do tipo many-to-many </li></ul></ul><ul><ul><li>Associações entre tabelas só podem ser one-to-many e one-to-one </li></ul></ul><ul><ul><ul><li>Necessidade de criar uma tabela de relacionamento para associações many-to-many </li></ul></ul></ul><ul><ul><ul><li>Tabela não presente no modelo do domínio da aplicação </li></ul></ul></ul>
  13. 13. Diferença dos Paradigmas: Custo <ul><li>Necessário escrever muito código para (tentar) contornar o problema </li></ul><ul><li>Código se torna repetitivo e de difícil manutenção </li></ul><ul><li>A escrita de código SQL pode tornar a aplicação dependente do banco de dados </li></ul><ul><li>Modelagem dos objetos fica prejudicada </li></ul><ul><li>Outras camada ficam fortemente acopladas à Camada de Persistência </li></ul><ul><li>Produtividade pode ser fortemente afetada </li></ul>
  14. 14. Estratégias de Persistência <ul><li>JDBC e SQL </li></ul><ul><ul><li>Faz parte da plataforma Java </li></ul></ul><ul><ul><li>Necessário escrever bastante código de baixo nível </li></ul></ul><ul><li>Stored Procedures </li></ul><ul><ul><li>Lógica de negócio sai da aplicação e vai para a base de dados </li></ul></ul><ul><ul><li>Perde-se a portabilidade </li></ul></ul>
  15. 15. Estratégias de Persistência <ul><li>Framework corporativo </li></ul><ul><ul><li>Necessário grande esforço da empresa </li></ul></ul><ul><ul><li>Demora-se muito para que a solução implementada atinga maturidade </li></ul></ul><ul><ul><li>Documentação muitas vezes é esquecida </li></ul></ul><ul><ul><li>Falta de suporte </li></ul></ul>
  16. 16. Estratégias de Persistência <ul><li>Java Persistence API (JPA) </li></ul><ul><ul><li>Especificação elaborada pelo Java Community Process para persistência em Java </li></ul></ul><ul><ul><li>Baseou-se em diversas soluções existentes </li></ul></ul><ul><ul><li>Frameworks existentes passaram a implementar a especificação </li></ul></ul><ul><ul><li>Recursos são um sub-conjunto dos encontrados nos frameworks que a implementam </li></ul></ul><ul><ul><li>Atualizações são lentas e burocráticas </li></ul></ul>
  17. 17. Estratégias de Persistência <ul><li>Frameworks de terceiros </li></ul><ul><ul><li>TopLink </li></ul></ul><ul><ul><ul><li>Framework de persistência Objeto/Relacional </li></ul></ul></ul><ul><ul><ul><li>Desenvolvido pela Oracle </li></ul></ul></ul><ul><ul><ul><li>Gratuito para avaliação e nas fases de desenvolvimento </li></ul></ul></ul><ul><ul><li>Hibernate </li></ul></ul>
  18. 18. Hibernate <ul><li>Framework de mapeamento Objeto-Relacional </li></ul><ul><li>Preenche a lacuna entre a base de dados relacional e a aplicação orientada a objetos </li></ul><ul><li>Framework de persistência Java mais utilizado e documentado </li></ul><ul><li>Mantido pela Jboss sob a licensa LGPL </li></ul><ul><li>Suporta classes desenvolvidas com agregação, herança, polimorfismo, composição e coleções </li></ul>
  19. 19. Hibernate <ul><li>Permite a escrita de consultas tanto através de uma linguagem própria (HQL) como também através de SQL </li></ul><ul><li>Framework não intrusivo </li></ul><ul><ul><li>Não restringe a arquitetura da aplicação </li></ul></ul><ul><li>Implementa a especificação Java Persistence API </li></ul><ul><li>Grande e ativa comunidade </li></ul><ul><ul><li>Mais de 25 mil desenvolvedores registrados nos foruns oficiais </li></ul></ul>
  20. 20. Mapeamento Objeto Relacional <ul><li>Permite a persistência de objetos em tabelas de uma base de dados relacional </li></ul><ul><li>Automática e Transparente </li></ul><ul><li>Utiliza metadados para descrever o relacionamento entre os objetos e a base de dados </li></ul><ul><ul><li>XML </li></ul></ul><ul><ul><li>Xdoclet </li></ul></ul><ul><ul><li>Annotations </li></ul></ul>
  21. 21. Mapeamento Objeto Relacional <ul><li>O SQL é gerado automaticamente a partir dos metadados </li></ul><ul><li>A escrita e manutenção de metadados necessita de esforço nas etapas de implementação </li></ul><ul><ul><li>Esforço bem menor do que o necessário para fazer a conversão manualmente </li></ul></ul><ul><li>A conversão entre os tipos de representação pode trazer perca de performance </li></ul><ul><ul><li>Ferramentas maduras otimizam a conversão em diversos pontos </li></ul></ul>
  22. 22. Mapeamento Objeto Relacional <ul><li>Possui quatro partes principais </li></ul><ul><ul><li>API para realização de operações básicas (CRUD) </li></ul></ul><ul><ul><li>Linguagem ou API para a realização de consultas </li></ul></ul><ul><ul><li>Maneira para a especificação de metadados </li></ul></ul><ul><ul><li>Técnicas de otimização </li></ul></ul><ul><ul><ul><li>Dirty checking </li></ul></ul></ul><ul><ul><ul><li>Carregamento tardio (lazy association fetching) </li></ul></ul></ul>
  23. 23. Mapeamento Objeto Relacional: Vantagens <ul><li>Produtividade </li></ul><ul><ul><li>Elimina a necessidade de escrita de grande parte do código relativo a persistência </li></ul></ul><ul><ul><li>Maior tempo disponível para implementar a lógica da aplicação </li></ul></ul><ul><li>Manutenibilidade </li></ul><ul><ul><li>Menos código </li></ul></ul><ul><ul><li>Maior entendimento da aplicação </li></ul></ul><ul><ul><li>Camada de abstração </li></ul></ul><ul><ul><li>Facilita a refatoração </li></ul></ul>
  24. 24. Vantagens <ul><li>Performance </li></ul><ul><ul><li>Tarefas manuais nem sempre tem performance melhor do que tarefas automatizadas </li></ul></ul><ul><ul><ul><li>Considerando limitações de custo e tempo </li></ul></ul></ul><ul><ul><li>Frameworks maduros são bastantes otimizados </li></ul></ul><ul><ul><li>Com o aumento de produtividade, você pode dedicar mais tempo para resolver possíveis gargalos </li></ul></ul><ul><li>Portabilidade </li></ul><ul><ul><li>Independência nem sempre é algo simples de ser alcançado, mesmo em aplicações Java </li></ul></ul><ul><ul><li>Suporte a diversos tipos de banco de dados </li></ul></ul>
  25. 25. Hibernate: Módulos <ul><li>Hibernate Core </li></ul><ul><ul><li>Contém os serviços básicos </li></ul></ul><ul><ul><li>Metadados escritos em XML </li></ul></ul><ul><ul><li>Consultas </li></ul></ul><ul><ul><ul><li>HQL: Hibernate Query Language </li></ul></ul></ul><ul><ul><ul><li>Interfaces utilizando critérios e exemplos </li></ul></ul></ul><ul><ul><li>Não depende de outros módulos </li></ul></ul><ul><ul><li>Não depende de uma versão específica do JDK </li></ul></ul><ul><ul><li>Executável em qualquer servidor Web e/ou de Aplicação e também em aplicações desktop </li></ul></ul>
  26. 26. Módulos <ul><li>Hibernate Annotations </li></ul><ul><ul><li>Permite a escrita de metadados através de Annotations </li></ul></ul><ul><ul><li>Beneficia-se da tipagem do Java </li></ul></ul><ul><ul><li>Compatível com refatorações de código </li></ul></ul><ul><ul><li>Semântica familiar para quem já está acostumado com metadados em XML </li></ul></ul><ul><ul><li>Utiliza as Annotations da especificação JPA </li></ul></ul><ul><ul><li>Possui Annotations próprias para configurações avançadas não presentes na especificação </li></ul></ul><ul><ul><li>Necessita do JDK 5.0 </li></ul></ul>
  27. 27. Módulos <ul><li>Hibernate Entity Manager </li></ul><ul><ul><li>Implementação da especificação JPA </li></ul></ul><ul><ul><li>Permite a escrita de código compatível com qualquer framework de persistência que implemente a especificação </li></ul></ul><ul><ul><li>Utiliza o pacote javax.persistence </li></ul></ul><ul><ul><li>Não disponibiliza todas as funcionalidades do Hibernate </li></ul></ul>
  28. 28. Separação em camadas <ul><li>É uma boa prática dividir aplicações de médio e grande porte em camadas </li></ul><ul><ul><li>Padrão Layers (Pattern-Oriented Software architecture) </li></ul></ul><ul><li>Divisão mais utilizada </li></ul><ul><ul><li>Apresentação </li></ul></ul><ul><ul><li>Negócio </li></ul></ul><ul><ul><li>Persistência </li></ul></ul>
  29. 29. Separação em camadas <ul><li>Permite a especificação de intefaces para os diversos tipos de serviços </li></ul><ul><ul><li>A implementação pode ser mudada sem afetar significativamente o código de outras camadas </li></ul></ul><ul><li>A comunicação ocorre das camadas superiores para as camadas inferiores </li></ul><ul><li>Uma camada só depende da camada imediatamente inferior </li></ul><ul><ul><li>Camada de apresentação não sabe da existência da camada de persistência </li></ul></ul>
  30. 31. Criando um projeto
  31. 32. Next >....
  32. 33. Finish
  33. 34. Adicionando as bibliotecas
  34. 35. Criando uma entidade @Entity @Table (name = &quot;MESSAGES&quot; ) public class Message { @Id @GeneratedValue @Column (name = &quot;MESSAGE_ID&quot; ) private Long id ; @Column (name = &quot;MESSAGE_TEXT&quot; ) private String text ; @ManyToOne (cascade = CascadeType. ALL ) @JoinColumn (name = &quot;NEXT_MESSAGE_ID&quot; ) private Message nextMessage ; private Message() {} public Message(String text) { this . text = text; } //gets e sets }
  35. 36. Annotations da classe <ul><li>Entity </li></ul><ul><ul><li>Informa que a classe pode ser persistida pelo Hibernate </li></ul></ul><ul><li>Table </li></ul><ul><ul><li>Informa o nome da tabela em que os objetos da classe devem ser armazenados </li></ul></ul>@Entity @Table (name = &quot;MESSAGES&quot; ) public class Message {
  36. 37. Construtores <ul><li>Obrigatório um construtor sem argumentos </li></ul>private Message() {} public Message(String text) { this . text = text; }
  37. 38. Propriedades <ul><li>Representa o identificador do objeto </li></ul><ul><li>Preenchido automaticamente quando o objeto é salvo </li></ul><ul><li>Mapeado para a chave primária da tabela </li></ul><ul><li>Se duas instâncias tiverem o mesmo identificador, elas representam a mesma linha da tabela </li></ul>@Id @GeneratedValue @Column (name = &quot;MESSAGE_ID&quot; ) private Long id ;
  38. 39. Atributos <ul><li>O atributo text é armazenado na coluna MESSAGE_TEXT </li></ul>@Column (name = &quot;MESSAGE_TEXT&quot; ) private String text ; <ul><li>O atributo nextMessage é uma associação many-to-one </li></ul><ul><li>Mapeado pela chave estrangeira NEXT_MESSAGE_ID </li></ul>@ManyToOne (cascade = CascadeType. ALL ) @JoinColumn (name = &quot;NEXT_MESSAGE_ID&quot; ) private Message nextMessage ;
  39. 40. Transparência <ul><li>Não há a necessidade de se herdar de uma superclasse ou de implementar um interface </li></ul><ul><ul><li>POJO - Plain Ordinary Java Objects </li></ul></ul><ul><li>Classes podem ser reutilizadas fora do contexto de persistência </li></ul><ul><ul><li>Interface com o usuário </li></ul></ul><ul><ul><li>Testes de unidades </li></ul></ul><ul><li>As entidades não precisam nem saber que serão persistidas </li></ul><ul><li>Grande nível de portabilidade </li></ul>
  40. 41. Configurando o Hibernate <ul><li>Configuração feita através do arquivo hibernate.cfg.xml </li></ul><ul><li>Deve estar localizado na raiz do classpath </li></ul><ul><ul><li>Localização default </li></ul></ul><ul><ul><li>Para projetos maven, utilizar a pasta src/main/resources </li></ul></ul><ul><li>Configurações contém </li></ul><ul><ul><li>Parâmetros de acesso a base de dados </li></ul></ul><ul><ul><li>Pool de conexões </li></ul></ul><ul><ul><li>Entidades a serem persistidas </li></ul></ul>
  41. 42. hibernate.cfg.xml < hibernate-configuration > < session-factory > <!-- Parâmetros de acesso a base de dados --> < property name = &quot;connection.driver_class&quot; > org.postgresql.Driver </ property > < property name = &quot;connection.url&quot; > jdbc:postgresql://localhost:5432/curso </ property > < property name = &quot;connection.username&quot; > postgresql </ property > < property name = &quot;connection.password&quot; > postgresql </ property > < property name = &quot;dialect&quot; > org.hibernate.dialect.PostgreSQLDialect </ property > ...
  42. 43. hibernate.cfg.xml ... <!-- Configuração do Pool de conexões --> < property name = &quot;c3p0.min_size&quot; > 5 </ property > < property name = &quot;c3p0.max_size&quot; > 20 </ property > < property name = &quot;c3p0.timeout&quot; > 300 </ property > < property name = &quot;c3p0.max_statements&quot; > 50 </ property > < property name = &quot;c3p0.idle_test_period&quot; > 3000 </ property > <!-- Exibe no console o SQL gerado pelo hibernate--> < property name = &quot;show_sql&quot; > true </ property > <!-- Cria e executa a DDL (tabelas, colunas, etc...)--> < property name = &quot;hbm2ddl.auto&quot; > create </ property > <!-- Informa as Entidades da aplicação --> < mapping class = &quot;br.gov.serpro.curso.hibernate.exemplo1.Message&quot; /> </ session-factory > </ hibernate-configuration >
  43. 44. 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( &quot;Hello World&quot; ); // Salvando a Mensagem Long msgId = (Long) session.save(message); //Fazendo o commit da transação tx.commit(); //Fechando o Session session.close(); HibernateUtil.shutdown();
  44. 45. Objetos utilizados <ul><li>Session </li></ul><ul><ul><li>Contém métodos utilizados para armazenar e recuperar entidades </li></ul></ul><ul><ul><li>Armazena uma lista de comandos SQL que serão executados, em algum momento, na base de dados </li></ul></ul><ul><ul><li>Mantém as entidades gerenciadas pelo Hibernate </li></ul></ul><ul><ul><ul><li>Recuperadas, inseridas ou atualizadas através do Session </li></ul></ul></ul><ul><ul><li>Único para cada thread </li></ul></ul>
  45. 46. Objetos utilizados <ul><li>Transaction </li></ul><ul><ul><li>Utilizado para delimitar as transações com a base de dados </li></ul></ul><ul><ul><li>Geralmente gerenciado pelo container </li></ul></ul><ul><ul><ul><li>EJB </li></ul></ul></ul><ul><ul><ul><li>Spring </li></ul></ul></ul><ul><li>SessionFactory </li></ul><ul><ul><li>Utilizado para criar os Session </li></ul></ul><ul><ul><li>Reutilizável por toda a aplicação </li></ul></ul>
  46. 47. HibernateUtil 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(); } }
  47. 48. Recuperando as Mensagens Session newSession = HibernateUtil.getSessionFactory().openSession(); Transaction newTransaction = newSession.beginTransaction(); //Criando e executando uma consulta Query query = newSession .createQuery( &quot;from Message m order by m.text asc&quot; ); List<Message> messages = query.list(); //Retornando a quantidade de mensagens encontradas System. out .println(messages.size() + &quot; message(s) found:&quot; ); //Retornando as mensagens encontradas for (Message msg : messages) { System. out .println(msg.getText()); } newTransaction.commit(); newSession.close(); HibernateUtil.shutdown();
  48. 49. Objetos Utilizados <ul><li>Query </li></ul><ul><ul><li>Cria as consultas </li></ul></ul><ul><ul><li>Associa os parâmetros </li></ul></ul><ul><ul><li>Executa as consultas </li></ul></ul>
  49. 50. 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( &quot;Greetings Earthling&quot; ); //Criando uma nova mensagem e associando à antiga message.setNextMessage( new Message( &quot;Take me to your leader&quot; )); thirdTransaction.commit(); thirdSession.close(); HibernateUtil.shutdown();
  50. 51. Dirty Checking e Cascade <ul><li>Dirty Checking </li></ul><ul><ul><li>O Hibernate automaticamente verifica quando um atributo é modificado </li></ul></ul><ul><ul><li>O atributo é atualizado na base de dados sem a necessidade de uma chamada explicita </li></ul></ul><ul><ul><li>É possível somente dentro de uma transação e para objetos gerenciados pelo Session </li></ul></ul><ul><li>Cascade </li></ul><ul><ul><li>Novas entidades são persistidas automaticamente </li></ul></ul><ul><ul><li>Devem ser alcançáveis a partir de uma entidade gerenciada </li></ul></ul>
  51. 52. Metadados <ul><li>Utilizados para especificar o mapeamento entre </li></ul><ul><ul><li>Classes e tabelas </li></ul></ul><ul><ul><li>Propriedades e colunas </li></ul></ul><ul><ul><li>Associações e chaves estrangeiras </li></ul></ul><ul><ul><li>Tipos de atributos Java e tipos de atributos SQL </li></ul></ul><ul><li>Pode ser escrita de duas formas </li></ul><ul><ul><li>Arquivos XML </li></ul></ul><ul><ul><li>Xdoclet </li></ul></ul><ul><ul><li>Java Annotations </li></ul></ul>
  52. 53. Porque não usar XML <ul><li>Pode ser tornar pouco legível e de difícil edição </li></ul><ul><ul><li>Requer maior digitação </li></ul></ul><ul><ul><li>Falta de valores default para atributos e elementos </li></ul></ul><ul><li>Não necessariamente mais flexível e mais fácil de manter do que código Java </li></ul><ul><li>Mais fácil encontrar um bom editor Java do que um bom editor de XML </li></ul>
  53. 54. Metadados com Annotations <ul><li>A meta-informação fica perto dos dados que ela descreve </li></ul><ul><li>Compatível com refatoração de código </li></ul><ul><ul><li>Renomear, deletar e remover classes e propriedades </li></ul></ul><ul><li>Sem necessidade de fazer parser em XML </li></ul><ul><ul><li>Inicialização mais rápida </li></ul></ul><ul><li>Lido através de reflection na inicialização do Hibernate </li></ul><ul><li>Disponível a partir da JDK 5.0 </li></ul>
  54. 55. Mapeando Propriedades <ul><li>Ao mapear uma classe através da Annotation @ Entity , todas as propriedades serão consideradas persistentes </li></ul><ul><li>Propriedades não persistentes devem receber a Annotation @ Transient ou o modificador transient </li></ul><ul><li>Por default, o nome da coluna será o mesmo da propriedade </li></ul><ul><li>Meio de acesso é o mesmo do @ID </li></ul><ul><ul><li>Definido na propriedade ou no método get() </li></ul></ul>
  55. 56. @Column <ul><li>Aplicável para propriedades simples </li></ul><ul><li>Atributos </li></ul><ul><ul><li>name </li></ul></ul><ul><ul><ul><li>Nome da coluna a qual a propriedade é mapeada </li></ul></ul></ul><ul><ul><li>unique </li></ul></ul><ul><ul><ul><li>Se o valor deve ser único ou não </li></ul></ul></ul><ul><ul><li>nullable </li></ul></ul><ul><ul><ul><li>Se a propriedade pode ser nula ou não </li></ul></ul></ul>
  56. 57. Mapeando Propriedades: Tipos
  57. 58. Mapeando Propriedades: Tipos
  58. 59. Datas <ul><li>Propriedades podem ser do tipo java.util.Date ou java.util.Calendar </li></ul><ul><li>Precisão default é TIMESTAMP </li></ul><ul><li>Precisão pode ser alterada através da Annotation @Temporal </li></ul>@Temporal (TemporalType. DATE ) private Date date1 ; @Temporal (TemporalType. TIME ) private Date date2 ; @Temporal (TemporalType. TIMESTAMP ) private Date date3 ;
  59. 60. Identidade das Entidades <ul><li>Identidade versus Equivalência em Java </li></ul><ul><ul><li>Identidade </li></ul></ul><ul><ul><ul><li>Operador == </li></ul></ul></ul><ul><ul><ul><li>Definido pela máquina virtual </li></ul></ul></ul><ul><ul><ul><li>Dois objetos são idênticos se eles apontam para o mesmo local da memória </li></ul></ul></ul><ul><ul><li>Equivalência </li></ul></ul><ul><ul><ul><li>Definida pelas classes que sobreescrevem o método equals() </li></ul></ul></ul><ul><ul><ul><li>Dois objetos diferentes possuem o mesmo valor </li></ul></ul></ul><ul><ul><ul><li>Dois objetos String podem ter a mesma seqüência de caracteres </li></ul></ul></ul>
  60. 61. Identidade das Entidades <ul><li>Identidade na base de dados </li></ul><ul><ul><li>Duas Entidades são idênticas se elas representam a mesma linha na base de dados </li></ul></ul><ul><ul><ul><li>Se são armazenadas na mesma tabela e possuem a mesma chave primária </li></ul></ul></ul>
  61. 62. Adicionando um Identificador <ul><li>O valor é gerado automaticamente pelo Hibernate </li></ul><ul><li>Não deve ser mudado pela aplicação </li></ul>@Entity @Table (name= &quot;CATEGORY&quot; ) public class Category { @Id @GeneratedValue (strategy = GenerationType. AUTO ) @Column (name = &quot;CATEGORY_ID&quot; ) private Long id ; public Long getId() { return id ; } }
  62. 63. Escolhendo a chave primária <ul><li>Uma chave candidata é uma coluna, ou um conjunto de colunas, que pode ser utilizada para identificar um registro na base de dados </li></ul><ul><li>Requisitos </li></ul><ul><ul><li>O valor nunca deve ser nulo </li></ul></ul><ul><ul><li>Cada registro deve ter um valor único </li></ul></ul><ul><ul><li>O valor nunca deve mudar </li></ul></ul>
  63. 64. Escolhendo a chave primária <ul><li>Chaves naturais são aquelas que possuem significado para o domínio da aplicação </li></ul><ul><ul><li>CPF de um usuário </li></ul></ul><ul><ul><li>Seqüencial gerado pela aplicação </li></ul></ul><ul><li>Dificilmente chaves naturais atendem os requisitos necessários </li></ul>
  64. 65. Escolhendo a chave primária <ul><li>Chaves cegas </li></ul><ul><ul><li>Melhor alternativa </li></ul></ul><ul><ul><li>Não possuem significado para o domínio da aplicação </li></ul></ul><ul><ul><li>Geradas pelo banco de dados ou pela aplicação </li></ul></ul>
  65. 66. Geração automática de chaves <ul><li>Hibernate suporta diversas estratégias para geração automática de chaves </li></ul><ul><li>A estratégia deve ser especificada através da Annotations @ GeneratedValue </li></ul>
  66. 67. Estratégias <ul><li>IDENTITY </li></ul><ul><ul><li>Suporte para colunas IDENTITY nos bancos de dados DB2, MySQL, MS SQL Server, Sybase e HypersonicSQL </li></ul></ul><ul><ul><li>Os tipos devem ser long , short ou int </li></ul></ul><ul><li>SEQUENCE </li></ul><ul><ul><li>Utiliza um Sequence para a geração de chaves </li></ul></ul><ul><ul><li>Suporte para DB2, PostgreSQL e Oracle dentre outros </li></ul></ul><ul><ul><li>Nome default da sequence é hibernate_sequence </li></ul></ul>
  67. 68. Estratégias <ul><li>increment </li></ul><ul><ul><li>Na inicialização o Hibernate lê qual o maior valor para a chave da tabela </li></ul></ul><ul><ul><li>O valor é atribuído e incrementado em cada inserção </li></ul></ul><ul><ul><li>Não deve ser utilizado se o Hibernate não tiver acesso exclusivo para a base de dados </li></ul></ul>
  68. 69. Estratégias <ul><li>AUTO </li></ul><ul><ul><li>Escolhe entre as estratégias IDENTITY, SEQUENCE ou HILO </li></ul></ul><ul><ul><li>Estratégia escolhida depende do banco de dados utilizado </li></ul></ul><ul><ul><li>Utilizado para manter a portabilidade </li></ul></ul><ul><li>Outras </li></ul><ul><ul><li>hilo, seqhilo, uuid.hex, guid, select </li></ul></ul><ul><ul><li>IdentifierGenerator </li></ul></ul><ul><ul><ul><li>Permite a implementação de sua própria estratégia </li></ul></ul></ul>
  69. 70. Mapeando Componentes <ul><li>Entidades são classes persistentes que representam objetos do domínio da aplicação </li></ul><ul><ul><li>Possuem identidade própria </li></ul></ul><ul><li>Hibernate suporta a construção de um modelo de objetos de alta granularidade </li></ul><ul><ul><li>Propriedades de uma Entidade podem ser encapsuladas em outros objetos </li></ul></ul><ul><ul><ul><li>Tais objetos não possuem identidade própria </li></ul></ul></ul><ul><ul><ul><li>Chamados de Objetos Valores ou Componentes </li></ul></ul></ul><ul><ul><li>Mais classes do que tabelas </li></ul></ul>
  70. 71. Mapeando Componentes
  71. 72. Mapeando Componentes <ul><li>User </li></ul><ul><ul><li>Representa uma Entidade </li></ul></ul><ul><ul><li>Possui identidade própria </li></ul></ul><ul><ul><ul><li>Chave primária na base de dados </li></ul></ul></ul><ul><ul><li>Uma referência para User é persistida como uma chave estrangeira </li></ul></ul><ul><ul><li>Tem seu próprio ciclo de vida </li></ul></ul><ul><ul><ul><li>Existe independentemente de qualquer outra entidade </li></ul></ul></ul>
  72. 73. Mapeando Componentes <ul><li>Address </li></ul><ul><ul><li>Representa um Componente </li></ul></ul><ul><ul><li>Não possui identidade própria </li></ul></ul><ul><ul><li>Pertence a Entidade User </li></ul></ul><ul><ul><li>Estado é persistido no registro referente ao User a qual está associado </li></ul></ul><ul><ul><li>Ciclo de vida dependente de User </li></ul></ul><ul><ul><li>Se dois Usuários morarem no mesmo apartamento, cada um tem uma referência para um objeto distinto </li></ul></ul><ul><ul><li>Comportamento similar a tipos como String e Integer </li></ul></ul>
  73. 74. Mapeando Componentes @Embeddable public class Address { @Column (name = &quot;ADDRESS_STREET&quot; , nullable = false ) private String street ; @Column (name = &quot;ADDRESS_CITY&quot; , nullable = false ) private String city ; //gets e sets... }
  74. 75. Mapeando Componentes @Entity @Table (name = &quot;USERS&quot; ) public class User { @Id @GeneratedValue (strategy=GenerationType. AUTO ) private Long id ; private String name ; private String email ; private Address address ; //gets e sets }
  75. 76. Mapeando Herança <ul><li>A utilização de uma tabela para cada entidade não funciona tão bem para heranças entre entidades </li></ul><ul><li>Bancos de dados SQL, de maneira geral, não possuem o conceito de herança </li></ul><ul><ul><li>Soluções proprietária podem comprometer a portabilidade da aplicação </li></ul></ul>
  76. 77. Estratégias <ul><li>Tabela por classe concreta </li></ul><ul><li>Tabela por classe concreta, utilizando junção </li></ul><ul><li>Tabela por hierarquia </li></ul><ul><li>Tabela por classe (concreta ou não) </li></ul>
  77. 78. Uma tabela por Classe Concreta: Modelagem
  78. 79. Uma tabela por Classe Concreta <ul><li>Estratégia mais simples </li></ul><ul><li>Todas propriedades de uma classe, incluindo as herdadas, são mapeadas para a mesma tabela </li></ul><ul><li>Mapeamento convencional pode ser utilizado </li></ul><ul><li>Não suporta associações polimórficas adequadamente </li></ul><ul><ul><li>Associação para classe abstrata necessitaria que a chave estrangeira referenciasse duas tabelas </li></ul></ul>
  79. 80. Uma tabela por Classe Concreta <ul><li>Diferentes colunas em diferentes tabelas passariam a possuir a mesma semântica </li></ul><ul><li>Recomendável somente para a hierarquia superior </li></ul><ul><ul><li>Associações polimórficas geralmente não necessárias e não recomendadas </li></ul></ul><ul><ul><li>Modificações na superclasse são muito raras </li></ul></ul>select CREDIT_CARD_ID, OWNER, NUMBER, EXP_MONTH, EXP_YEAR ... from CREDIT_CARD select BANK_ACCOUNT_ID, OWNER, ACCOUNT, BANKNAME, ... from BANK_ACCOUNT
  80. 81. Mapeando a Superclasse <ul><li>Mapear a super classe através da Annotattion @ MappedSuperclass </li></ul>@MappedSuperclass public abstract class BillingDetails { @Column (name = &quot;OWNER&quot; , nullable = false ) private String owner ; //gets e sets... }
  81. 82. Mapeando as Subclasses <ul><li>Nenhuma configuração extra é necessária </li></ul>@Entity public class BankAccount extends BillingDetails{ @Id @GeneratedValue private Long id ; private Integer account ; private String bank ; }
  82. 83. Mapeando as Subclasses <ul><li>Mapeamento das propriedades herdadas pode ser alterado </li></ul><ul><li>Adicionar a Annotation @AttributeOverride </li></ul>@Entity @AttributeOverride (name = &quot;owner&quot; , column = @Column (name = &quot;CC_OWNER&quot; , nullable = false )) public class CreditCard extends BillingDetails { @Id @GeneratedValue private Long id ; private String number ; }
  83. 84. Uma tabela por Classe Concreta: Union <ul><li>Com a utilização de consultas com Union, alguns problemas podem ser eliminados </li></ul><ul><li>Suporte a associações polimórficas </li></ul><ul><ul><li>Hibernate utiliza o Union para simular uma única tabela </li></ul></ul><ul><li>As subclasses herdam o Id da super-classe </li></ul>
  84. 85. Mapeando a Super Classe <ul><li>É utilizada a Annotation @Inheritance </li></ul>@Entity @Inheritance (strategy = InheritanceType. TABLE_PER_CLASS ) public class BillingDetails { @Id @ GeneratedValue @Column (name = &quot;BILLING_DETAILS_ID&quot; ) private Long id = null ; @Column (name = &quot;OWNER&quot; , nullable = false ) private String owner ; }
  85. 86. Mapeando as Subclasses <ul><li>Não é necessário mapear o identificador </li></ul><ul><ul><li>O Identificador é mapeado na super-classe </li></ul></ul>@Entity public class CreditCard extends BillingDetails{ @Column (name = &quot;CC_NUMBER&quot; ) private String number ; }
  86. 87. Tabela por Hierarquia
  87. 88. Tabela por Hierarquia <ul><li>Toda uma hierarquia é mapeada em uma única tabela </li></ul><ul><li>A tabela possui colunas para todas as propriedades de todas as entidades da hierarquia </li></ul><ul><li>A subclasse de cada registro é identificada através de uma coluna discriminatória </li></ul><ul><li>Vantagem </li></ul><ul><ul><li>Possui a melhor performance </li></ul></ul>
  88. 89. Tabela por Hierarquia <ul><li>Desvantagens </li></ul><ul><ul><li>Valores para colunas das subclasses devem sempre permitir NULL </li></ul></ul><ul><ul><ul><li>Perca da restrição NOT NULL </li></ul></ul></ul><ul><ul><li>Dados são desnormalizados </li></ul></ul>
  89. 90. Mapeando a Superclasse <ul><li>O valor do atributo strategy deve ser mudado para InheritanceType.SINGLE_TABLE </li></ul>@Entity @Inheritance (strategy = InheritanceType. SINGLE_TABLE ) public abstract class BillingDetails { @Id @GeneratedValue @Column (name = &quot;BILLING_DETAILS_ID&quot; ) private Long id = null ; @Column (name = &quot;OWNER&quot; , nullable = false ) private String owner ; }
  90. 91. Tabela por classe
  91. 92. Tabela por classe <ul><li>Uma tabela para todas as classes, incluindo as abstratas, que possuem propriedades para serem persistidas </li></ul><ul><li>Relação de herança é representada por uma chave estrangeira </li></ul><ul><li>As tabelas não contém colunas para as propriedades herdadas </li></ul><ul><li>A chave primária é também uma chave estrangeira para a super classe </li></ul>
  92. 93. Tabela por classe <ul><li>Vantagens </li></ul><ul><ul><li>Os dados são normalizados </li></ul></ul><ul><ul><li>Restrições podem ser mantidas </li></ul></ul><ul><li>Desvantagens </li></ul><ul><ul><li>Performance pode ser muito baixa para hierarquias complexas </li></ul></ul><ul><ul><ul><li>Necessidade de muitas junções </li></ul></ul></ul>
  93. 94. Mapeando a Superclasse <ul><li>O valor do atributo strategy deve ser mudado para InheritanceType.JOINED </li></ul>@Entity @Inheritance (strategy = InheritanceType. JOINED ) public abstract class BillingDetails { @Id @GeneratedValue @Column (name = &quot;BILLING_DETAILS_ID&quot; ) private Long id = null ; @Column (name = &quot;OWNER&quot; , nullable = false ) private String owner ; }
  94. 95. Mapeando as Subclasses <ul><li>Id é mapeado na super-classe </li></ul>@Entity public class CreditCard extends BillingDetails{ @Column (name = &quot;CC_NUMBER&quot; ) private String number ; }
  95. 96. Escolhendo a melhor estratégia <ul><li>Tabela por classe concreta, utilizando junção </li></ul><ul><ul><li>Se associações ou consultas polimórficas nunca ou raramente são utilizadas </li></ul></ul><ul><li>Tabela por hierarquia </li></ul><ul><ul><li>Se associações ou consultas polimórficas são utilizadas e </li></ul></ul><ul><ul><li>Se as subclasses declaram poucas propriedades </li></ul></ul><ul><ul><ul><li>Maior diferença entre as subclasses é o comportamento </li></ul></ul></ul>
  96. 97. Escolhendo a Melhor Estratégia <ul><li>Tabela por Classe </li></ul><ul><ul><li>Se associações ou consultas polimórficas são utilizadas e </li></ul></ul><ul><ul><li>Se as subclasses declaram muitas propriedades </li></ul></ul><ul><ul><ul><li>Maior diferença entre as subclasses são os dados que elas armazenam </li></ul></ul></ul><ul><ul><li>Se a largura e o comprimento da hierarquia não for muito grande </li></ul></ul>
  97. 98. Mapeando coleções <ul><li>Objetos podem possuir coleções </li></ul><ul><li>As coleções podem ter duas naturezas </li></ul><ul><ul><li>Coleções de valores </li></ul></ul><ul><ul><ul><li>Tipos primitivos </li></ul></ul></ul><ul><ul><ul><li>Componentes </li></ul></ul></ul><ul><ul><li>Coleções de entidades </li></ul></ul>
  98. 99. Coleção de tipos primitivos: Set <ul><li>Um Item possui um conjunto de imagens </li></ul><ul><li>Somente o nome da imagem é persistido </li></ul><ul><li>Nomes não devem ser duplicados para um determinado Item </li></ul>
  99. 100. Annotations <ul><li>@CollectionOfElements </li></ul><ul><ul><li>Utilizada para coleções de tipos primitivos ou para coleções de objetos valores </li></ul></ul><ul><li>@JoinTable </li></ul><ul><ul><li>Informa a tabela em que a coleção é persistida </li></ul></ul><ul><ul><li>Atributos </li></ul></ul><ul><ul><ul><li>Name </li></ul></ul></ul><ul><ul><ul><ul><li>Nome da tabela </li></ul></ul></ul></ul><ul><ul><ul><li>JoinColumns </li></ul></ul></ul><ul><ul><ul><ul><li>Coluna que é chave estrangeira </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Chave estrangeira referencia a tabela da entidade que possui a coleção </li></ul></ul></ul></ul>
  100. 101. Annotations <ul><li>@JoinColumn </li></ul><ul><ul><li>É o tipo do atributo JoinColumns da Annotation @JoinTable </li></ul></ul><ul><ul><ul><li>Annotation dentro de outra Annotation </li></ul></ul></ul><ul><ul><li>Mapeia a coluna utilizada para junções </li></ul></ul><ul><ul><li>Atributos </li></ul></ul><ul><ul><ul><li>Name </li></ul></ul></ul><ul><ul><ul><ul><li>Nome da coluna </li></ul></ul></ul></ul>
  101. 102. Classe Item @Entity public class Item { @Id @GeneratedValue @Column (name = &quot;ITEM_ID&quot; ) private Long id ; private String name ; @CollectionOfElements @JoinTable (name = &quot;ITEM_IMAGE&quot; , joinColumns = @JoinColumn (name = &quot;ITEM_ID&quot; )) @Column (name = &quot;FILENAME&quot; , nullable = false ) private Set<String> images = new HashSet<String>(); }
  102. 103. Coleção de tipos primitivos: List <ul><li>Caso a aplicação necessite guardar a ordem dos elementos </li></ul><ul><li>Necessário uma coluna para informar a posição de cada elemento </li></ul>
  103. 104. Classe Item <ul><li>Deve-se adicionar a Annotation @IndexColumn </li></ul>@Entity public class Item { ... @CollectionOfElements @JoinTable (name = &quot;ITEM_IMAGE&quot; , joinColumns = @JoinColumn (name = &quot;ITEM_ID&quot; )) @Column (name = &quot;FILENAME&quot; , nullable = false ) @IndexColumn (name = &quot;POSITION&quot; ) private List<String> images = new ArrayList<String>(); }
  104. 105. Coleção de tipos primitivos: Map <ul><li>Se o Item possuir um Map de imagens </li></ul><ul><li>É necessário guardar o elemento e sua chave </li></ul>
  105. 106. Classe Item <ul><li>Utilizar a Annotation @MapKey </li></ul><ul><ul><li>Atributo columns informa o nome da coluna que armazena a chave </li></ul></ul>@Entity public class Item { ... @CollectionOfElements @JoinTable (name = &quot;ITEM_IMAGE&quot; , joinColumns = @JoinColumn (name = &quot;ITEM_ID&quot; )) @Column (name = &quot;FILENAME&quot; , nullable = false ) @MapKey (columns = @Column (name = &quot;IMAGENAME&quot; )) private Map<String, String> images = new HashMap<String, String>(); }
  106. 107. Associação entre Entidades <ul><li>Podem ser de diversas multiplicidades </li></ul><ul><ul><li>One-to-many </li></ul></ul><ul><ul><li>One-to-one </li></ul></ul><ul><ul><li>Many-to-many </li></ul></ul><ul><ul><li>Many-to-one </li></ul></ul><ul><li>Também são implementadas através de atributos </li></ul><ul><li>Para associações one-to-many e many-to-many é necessário a utilização de coleções </li></ul>
  107. 108. Implementando associações <ul><li>Coleções devem ser acessadas através de suas Interfaces </li></ul><ul><ul><li>Set, ao invés de HashSet </li></ul></ul><ul><ul><li>List, ao invés de ArrayList </li></ul></ul>
  108. 109. Associações Bidirecionais <ul><li>Os dois lados da associação devem estar consistentes </li></ul><ul><ul><li>Necessário mesmo para aplicações que não usam Hibernate </li></ul></ul>
  109. 110. Classe Category public class Category { private String name ; private Category parentCategory ; private Set<Category> childCategories = new HashSet<Category>(); //gets e sets //... }
  110. 111. Mantendo a Consistência Category aParent = new Category(); Category aChild = new Category(); aChild.setParentCategory(aParent); aParent.getChildCategories().add(aChild);
  111. 112. Relacionamento Pai-Filho
  112. 113. Classe Bid <ul><li>Relaciona-se a somente um Item </li></ul><ul><li>Mapeamento realizado através da Annotation @ManyToOne </li></ul><ul><li>Annotation @JoinColumn informa qual a chave estrangeira </li></ul><ul><ul><li>Atributo name </li></ul></ul><ul><ul><ul><li>Nome da coluna </li></ul></ul></ul><ul><ul><li>Atributo nullable </li></ul></ul><ul><ul><ul><li>Se o relacionamento é opcional ou não </li></ul></ul></ul>
  113. 114. Classe Bid @Entity public class Bid { @Id @GeneratedValue @Column (name = &quot;BID_ID&quot; ) private Long id ; private Integer amount ; @ManyToOne @JoinColumn (name = &quot;ITEM_ID&quot; , nullable = false ) private Item item ; }
  114. 115. Relacionamento Bidirecional <ul><li>O relacionamento pode ou não ser declarado como bidirecional </li></ul><ul><li>Para relacionamentos bidirecionais o outro lado da associação é mapeado com a Annotation inversa </li></ul><ul><ul><li>@OneToMany no caso de Item </li></ul></ul><ul><ul><ul><li>Classe Bid utiliza a Annotation @ManyToOne </li></ul></ul></ul>
  115. 116. Relacionamento Bidirecional @Entity public class Item { @Id @GeneratedValue @Column (name = &quot;ITEM_ID&quot; ) private Long id ; private String name ; @OneToMany (mappedBy = &quot;item&quot; ) private Set<Bid> bids = new HashSet<Bid>(); }
  116. 117. Relacionamento Bidirecional <ul><li>@OneToMany(mappedBy = &quot;item&quot;) </li></ul><ul><ul><li>Detalhes do mapeamento são configurados no outro lado da associação </li></ul></ul><ul><ul><ul><li>Através da Annotation @ManyToOne </li></ul></ul></ul><ul><li>Quando as referências de uma associação mudam, as duas propriedades são alteradas </li></ul><ul><ul><li>bid.setItem(item); </li></ul></ul><ul><ul><li>item.getBids().add(bid); </li></ul></ul>
  117. 118. Relacionamento Bidirecional <ul><li>Na base de dados somente uma atualização precisa ser feita </li></ul><ul><ul><li>Atualização da chave estrangeira </li></ul></ul><ul><ul><li>Hibernate não precisa executar dois comandos UPDATE </li></ul></ul><ul><li>Uma das alterações é sincronizada e a outra é ignorada </li></ul><ul><ul><li>Não há efeito colateral se as associações estiverem consistentes </li></ul></ul>
  118. 119. Relacionamento Bidirecional <ul><li>O lado que contém os detalhes do mapeamento é o lado que é sincronizado </li></ul><ul><ul><li>Relacionamentos many-to-one ou one-to-many </li></ul></ul><ul><ul><ul><li>Lado Many é sincronizado </li></ul></ul></ul><ul><ul><li>Relacionamento one-to-one </li></ul></ul><ul><ul><ul><li>Lado que possuir a chave estrangeira é sincronizado </li></ul></ul></ul><ul><ul><li>Relacionamento many-to-many </li></ul></ul><ul><ul><ul><li>Lado que mapear a tabela de junção é sincronizado </li></ul></ul></ul><ul><li>Os lados do relacionamento não sincronizados possuem o atributo mappedBy na Annotation </li></ul>
  119. 120. Relacionamento Bidirecional Bid bid = new Bid(); bid.setAmount(Integer. valueOf (1000)); Item item = new Item(); item.setName( &quot;computador&quot; ); bid.setItem(item); item.getBids(). add (bid); Session session = HibernateUtil. getSessionFactory ().openSession(); Transaction transaction = session.beginTransaction(); //O item tem que ser salvo primeiro session.save(item); session.save(bid);
  120. 121. Relacionamento One-to-One
  121. 122. One-to-One <ul><li>O atributo deve conter a Annotation @OneToOne </li></ul><ul><li>Se o relacionamento for bidirecional os dois atributos devem conter a Annotation </li></ul><ul><li>Em uma das propriedades deve ser adicionada a Annotation @JoinColumn </li></ul><ul><li>Na outra propriedade deve ser adicionado o atributo mappedBy à Annotation @OneToOne </li></ul>
  122. 123. Classe User @Entity @Table (name = &quot;USERS&quot; ) public class User { @Id @GeneratedValue (strategy=GenerationType. AUTO ) private Long id ; private String name ; @OneToOne @JoinColumn (name = &quot;SHIPPING_ADDRESS_ID&quot; ) private Address address ; }
  123. 124. Classe Address @Entity public class Address { @Id @GeneratedValue private Long id ; @Column (nullable = false ) private String street ; @OneToOne (mappedBy = &quot;address&quot; ) private User user ; }
  124. 125. Ralacionamento Many-to-Many
  125. 126. Many-to-Many <ul><li>O atributo deve conter a Annotation @ManyToMany </li></ul><ul><li>Se o relacionamento for bidirecional os dois atributos devem conter a Annotation </li></ul><ul><li>Em uma das propriedades deve ser adicionada a Annotation @JoinTable </li></ul><ul><li>Na outra propriedade deve ser adicionado o atributo mappedBy à Annotation @ManyToMany </li></ul>
  126. 127. @JoinTable <ul><li>Contém o nome da tabela de relacionamento </li></ul><ul><li>O atributo joinColumns mapeia a coluna associada à entidade mapeada </li></ul><ul><ul><li>O tipo do atributo é @JoinColumn </li></ul></ul><ul><ul><ul><li>Annotation dentro de annotation </li></ul></ul></ul><ul><li>O atributo inverseJoinColumns mapeia a coluna associada à outra entidade </li></ul><ul><ul><li>O tipo do atributo também é @JoinColumn </li></ul></ul>
  127. 128. Classe Category @Entity public class Category { @Id @GeneratedValue @Column (name = &quot;CATEGORY_ID&quot; ) private Long id ; private String name ; @ManyToMany @JoinTable (name = &quot;CATEGORY_ITEM&quot; , joinColumns = @JoinColumn (name = &quot;CATEGORY_ID&quot; ), inverseJoinColumns = @JoinColumn (name = &quot;ITEM_ID&quot; )) private Set<Item> items = new HashSet<Item>(); }
  128. 129. Classe Item @Entity public class Item { @Id @GeneratedValue @Column (name = &quot;ITEM_ID&quot; ) private Long id ; private String name ; @ManyToMany (mappedBy = &quot;items&quot; ) private Set<Category> categories = new HashSet<Category>(); }
  129. 130. Polimorfismo e LazyLoading <ul><li>Utilizando-se polimorfismo, as entidades são referenciadas através de suas super classes </li></ul><ul><li>Não se deve fazer o cast da referência para alguma das subclasses, mesmo que se saiba o tipo do objeto </li></ul><ul><li>Para associações carregadas por LazyLoading, é utilizado um objeto proxy </li></ul><ul><li>O objeto proxy não pode ser atribuído a uma subclasse da classe referenciada </li></ul>
  130. 131. Associações: Polimorfismo
  131. 132. Entidade User @Entity @Table (name = &quot;USERS&quot; ) public class User { @Id@GeneratedValue private Long id ; @OneToOne (fetch = FetchType. LAZY ) @JoinColumn (name = &quot;DEFAULT_BILLING_ID&quot; ) private BillingDetails defaultBilling ; }
  132. 133. Polimorfismo e LazyLoading User user = (User) session.get(User. class , userId); BillingDetails bd = user.getDefaultBilling(); CreditCard cc = (CreditCard) session.load(CreditCard. class , bd.getId()); System. out .println(cc.getNumber()); User user = (User) session.get(User. class , userId); BillingDetails billingDetails = user.getDefaultBilling(); //imprime false System. out .println(billingDetails instanceof CreditCard); //ClassCastException CreditCard creditCard = (CreditCard) billingDetails;
  133. 134. Ciclo de Vida dos Objetos <ul><li>Em seu ciclo de vida, uma entidade pode assumir diversos estados relativos a sua persistência </li></ul><ul><ul><li>Transiente </li></ul></ul><ul><ul><li>Persistente </li></ul></ul><ul><ul><li>Desconectada </li></ul></ul><ul><ul><li>Removida </li></ul></ul><ul><li>Entidades devem se comportar de maneira apropriada mesmo que ainda não estejam persistentes </li></ul>
  134. 135. Ciclo de Vida dos Objetos <ul><li>O ciclo de vida de uma entidade pode ser afetado através de chamadas às interfaces do Hibernate </li></ul><ul><ul><li>Operações de alterações e consultas na base de dados </li></ul></ul><ul><ul><li>Operações para delimitar a existência de uma transação e de um Sesssion </li></ul></ul><ul><li>Para o correta implementação, a aplicação deve se preocupar com o estado e o ciclo de vida do objeto </li></ul>
  135. 136. Ciclo de Vida dos Objetos: Conceitos <ul><li>Unidade de trabalho </li></ul><ul><ul><li>Conjunto de operações, geralmente atômicas </li></ul></ul><ul><li>Contexto de persistência </li></ul><ul><ul><li>Cache de todas alterações feitas em entidades em uma única unidade de trabalho </li></ul></ul>
  136. 137. Estado Transiente <ul><li>É o estado que um objeto assume quando é criado através do operador new </li></ul><ul><li>Não está associado a nenhum registro da base de dados </li></ul><ul><li>Os dados são perdidos quando o objeto não é mais referenciado e torna-se disponível para o Coletor de Lixo </li></ul><ul><li>Não são gerenciados pelo Hibernate </li></ul><ul><ul><li>Não possuem comportamento transacional </li></ul></ul>
  137. 138. Estado Persistente <ul><li>É uma entidade com um identificador na base de dados </li></ul><ul><ul><li>Possui uma chave primária </li></ul></ul><ul><li>São objetos gerenciados pelo Hibernate </li></ul><ul><li>Podem ser objetos criados pela aplicação </li></ul><ul><ul><li>Tornam-se persistentes através de chamadas ao Hibernate </li></ul></ul><ul><ul><li>Tornam-se persistentes se passarem a ser referenciados por outros objetos persistentes </li></ul></ul><ul><ul><ul><li>Depende do tipo de Cascade </li></ul></ul></ul>
  138. 139. Persistente <ul><li>Podem ser objetos retornados da base de dados </li></ul><ul><ul><li>Através de uma consulta </li></ul></ul><ul><ul><li>Através de uma associação entre um objeto persistente </li></ul></ul><ul><li>Podem ser objetos atualizados na base de dados </li></ul><ul><li>São sempre associados a um Contexto de Persistência </li></ul><ul><li>São guardados em um cache </li></ul><ul><li>Hibernate identifica qualquer alteração realizado no objeto </li></ul>
  139. 140. Removido <ul><li>Um objeto pode ser removido de duas maneiras </li></ul><ul><ul><li>Uma chamada explicita ao Hibernate </li></ul></ul><ul><ul><li>Através de uma operação com Cascade </li></ul></ul><ul><li>Um objeto neste estado é removido ao final da Unidade de Trabalho </li></ul><ul><ul><li>É gerenciado pelo Contexto de Persistência até que a Unidade de Trabalho termine </li></ul></ul>
  140. 141. Desconectado <ul><li>Objetos Persistentes passam para o estado Desconectado quando a Unidade de Trabalho é completada e o Contexto de Persistência é encerrado </li></ul><ul><li>O objeto não é mais sincronizado com a base de dados </li></ul><ul><li>Os dados do objeto podem se tornar desatualizados </li></ul><ul><li>Seus dados ainda podem ser alterados pela aplicação </li></ul><ul><li>Podem voltar ao estado Persistente </li></ul>
  141. 142. Contexto de Persistência <ul><li>Mantém um cache de instâncias gerenciadas </li></ul><ul><ul><li>Entidades no estado Persistente e Removido </li></ul></ul><ul><li>Conceito abstrato </li></ul><ul><ul><li>Não representado por um único objeto </li></ul></ul><ul><li>Cada objeto Session possui um Contexto de Persistência </li></ul><ul><li>Permite Dirty Checking automático </li></ul><ul><li>Delimita um escopo para a identidade das Entidades </li></ul><ul><ul><li>Não possui instâncias duplicadas </li></ul></ul>
  142. 143. Dirty Checking Automático <ul><li>É possível através do Contexto de Persistência </li></ul><ul><li>O dados de uma entidade são sincronizados com a base de dados </li></ul><ul><ul><li>No final da unidade de trabalho </li></ul></ul><ul><ul><li>Em outros momentos: antes de uma consulta </li></ul></ul><ul><li>Somente os objetos alterados são atualizados na base de dados </li></ul><ul><li>Atualização é retardada o máximo possível e é feita de forma automática </li></ul><ul><ul><li>Tempo de Lock do banco de dados é reduzido </li></ul></ul>
  143. 144. Cache de Primeiro Nível <ul><li>Armazenado no Contexto de Persistência </li></ul><ul><li>Mantém todas as instâncias de uma Unidade de Trabalho </li></ul><ul><li>Provê ganho de performance para a aplicação </li></ul><ul><li>Torna possível Repeatable Read </li></ul><ul><ul><li>Ao buscar mais de uma vez uma mesma entidade, os dados retornados são os mesmos </li></ul></ul><ul><li>O escopo é restrito à thread de execução </li></ul>
  144. 145. Cache de Primeiro Nível <ul><li>Um único objeto representa um determinado registro na base de dados </li></ul><ul><ul><li>Evita alterações conflitantes </li></ul></ul>
  145. 146. Contexto Persistência: Escopo <ul><li>Algumas funcionalidades da aplicação necessitam de diversas requisições para serem completadas </li></ul><ul><li>O escopo do Contexto de Persistência pode, ou não, ser o mesmo da funcionalidade </li></ul><ul><li>Duas estratégias são as mais utilizadas para delimitar o escopo do Contexto de Persistência </li></ul><ul><ul><li>Um objeto Session por requisição </li></ul></ul><ul><ul><li>Unidade de Trabalho de longa duração </li></ul></ul>
  146. 147. Uma Session por Requisição <ul><li>Quando o servidor recebe alguma requisição que requer acesso a base de dados uma nova Unidade de Trabalho é iniciada </li></ul><ul><li>A Unidade de Trabalho é encerrada quando a requisição é processada e a resposta está pronta para ser enviada ao usuário </li></ul><ul><li>As entidades são mantidas em estado Desconectado entre uma requisição e outra </li></ul>
  147. 148. Uma Session por Requisição <ul><li>Entidades mantidas entre duas requisições necessitam ser reconectadas para acessar serviços de persistência novamente </li></ul><ul><li>Qualquer alteração feita em entidades desconectadas deve ser sincronizada manualmente </li></ul><ul><ul><li>Operações de atualização e/ou merge </li></ul></ul>
  148. 149. Objetos Desconectados
  149. 150. Unidade de Trabalho de Longa Duração <ul><li>Objeto Session é mantido aberto durante várias requisições </li></ul><ul><ul><li>O Contexto de Persistência se propaga durante toda a conversação </li></ul></ul><ul><li>Conexões com a base de dados não são mantidas abertas </li></ul><ul><ul><li>A cada nova requisição o contexto é reconectado à base de dados </li></ul></ul><ul><li>As entidades são mantidas no estado Persistente </li></ul><ul><ul><li>Não requer merge ou atualização manual </li></ul></ul>
  150. 151. Unidade de Trabalho de Longa Duração <ul><li>No final da conversação, o Contexto é sincronizado com a base de dados e encerrado </li></ul><ul><li>A atomicidade das alterações é relativa à funcionalidade como um todo </li></ul>
  151. 152. Contexto expandido
  152. 153. Escopo limitado ao Contexto de Persistência Session session = HibernateUtil. getSessionFactory ().openSession(); Transaction transaction = session.beginTransaction(); Long id = (Long) session.save( new Message( &quot;Hibernate&quot; )); Message messageB = (Message) session.get(Message. class , id); Message messageC = (Message) session.get(Message. class , id); System. out .println(messageB.equals(messageC)); transaction.commit(); session.close(); Session session2 = HibernateUtil. getSessionFactory ().openSession(); Transaction transaction2 = session2.beginTransaction(); Message messageD = (Message) session2.get(Message. class , id); System. out .println(messageC.equals(messageD));
  153. 154. Identidade de objetos Desconectados <ul><li>Sempre que se for trabalhar com objetos desconectados, deve-se sobrescrever o método equals() </li></ul><ul><ul><li>Para objetos desconectados a garantia de uma única instância por registro é perdida </li></ul></ul><ul><ul><li>Implementação default não garante o comportamento desejado </li></ul></ul><ul><ul><li>Mesmo que dois objetos possuam todas as propriedades iguais, o método pode retornar false </li></ul></ul>
  154. 155. equals() <ul><li>Deve retornar verdadeiro se duas instâncias corresponderem ao mesmo registro </li></ul><ul><li>Quais propriedades devem ser comparadas? </li></ul><ul><li>Somente a chave primária </li></ul><ul><ul><li>Problema: entidades transientes não possuem valores para a chave primária </li></ul></ul><ul><li>Todas as propriedades </li></ul><ul><ul><li>Problema: entidades referentes ao mesmo registro não são consideradas iguais se alguma propriedade mudar </li></ul></ul><ul><li>Melhor abordagem: comparar a chave de negócio </li></ul>
  155. 156. Chave de negócio <ul><li>Uma propriedade, ou um conjunto delas, que é único para cada registro </li></ul><ul><ul><li>Chave candidata </li></ul></ul><ul><li>Não precisa ser imutável, basta que mude com pouca freqüência </li></ul>
  156. 157. Implementação public boolean equals(Object other) { if (!(other instanceof User)){ return false ; } User that = (User) other; return this . name .equals(that.getName()); } public int hashCode() { return this . name .hashCode(); }
  157. 158. Interagindo com o Hibernate <ul><li>O Hibernate provê diversos serviços </li></ul><ul><ul><li>Operações CRUD </li></ul></ul><ul><ul><ul><li>Criar </li></ul></ul></ul><ul><ul><ul><li>Recuperar </li></ul></ul></ul><ul><ul><ul><li>Atualizar </li></ul></ul></ul><ul><ul><ul><li>Deletar </li></ul></ul></ul><ul><ul><li>Realização de consultas </li></ul></ul><ul><ul><li>Controle de transação </li></ul></ul><ul><ul><li>Gerenciamento do Contexto de Persistência </li></ul></ul>
  158. 159. Interagindo com o Hibernate <ul><li>Os serviços são disponibilizados através de diversas Interfaces </li></ul><ul><ul><li>Session </li></ul></ul><ul><ul><li>Transaction </li></ul></ul><ul><ul><li>Query </li></ul></ul><ul><ul><li>Criteria </li></ul></ul>
  159. 160. Armazenando e Recuperando Objetos <ul><li>Para armazenar ou recuperar objetos, é necessário iniciar uma Unidade de Trabalho </li></ul>Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); <ul><li>Um Contexto de Persistência é criado </li></ul><ul><ul><li>Irá gerenciar todas as entidades do Session </li></ul></ul><ul><li>Uma transação também deve ser iniciada </li></ul><ul><ul><li>mesmo para operações de leitura </li></ul></ul>
  160. 161. Armazenando um Objeto // Quando é instanciado, o item está no estado Transiente Item item = new Item(); item.setName( &quot;Item 1&quot; ); // um novo Session é aberto Session session = HibernateUtil. getSessionFactory ().openSession(); Transaction transaction = session.beginTransaction(); // O item passa para o estado Persistente e fica associado //ao Session e ao Contexto de Persistência session.save(item); //As mundanças são sincronizadas com a base de dados transaction.commit(); //O Session é fechado e o Contexto de Persistência encerrado. //O item passa para o estado Desconectado session.close();
  161. 162. Armazenando um Objeto
  162. 163. Recuperando uma Entidade Session session = HibernateUtil. getSessionFactory ().openSession(); Transaction tx = session.beginTransaction(); //Item é recuperado no estado Transiente Item item = (Item) session.load(Item. class , new Long(1234)); // Item item = (Item) session.get(Item.class, new Long(1234)); tx.commit(); //Item passa para o estado Desconectado session.close();
  163. 164. Recuperando uma Entidade
  164. 165. Recuperando uma Entidade <ul><li>Método get() </li></ul><ul><ul><li>Se o objeto procurado não for encontrado, retorna null </li></ul></ul><ul><li>Método load() </li></ul><ul><ul><li>Se o objeto procurado não for encontrado, lança a exceção ObjectNotFoundException </li></ul></ul><ul><ul><li>A existência do objeto só é verificada quando alguma propriedade é acessada </li></ul></ul>
  165. 166. Modificando um Objeto Persistente <ul><li>Todo objeto retornado pelos métodos load() ou get() ou através de uma consulta, assume o estado Persistente </li></ul><ul><li>Os objetos podem ser modificados e as alterações são sincronizadas com a base de dados </li></ul>
  166. 167. Modificando um Objeto Persistente Long id = armazenarItem (); Session session = HibernateUtil. getSessionFactory ().openSession(); Transaction tx = session.beginTransaction(); Item item = (Item) session.get(Item. class , id); item.setName( &quot;Playstation&quot; ); //Dados sincronizados com a base de dados. Dirty Cheking automático tx.commit(); session.close();
  167. 168. Modificando um Objeto Persistente
  168. 169. De Persistente para Transiente Long id = armazenarItem (); Session session = HibernateUtil. getSessionFactory ().openSession(); Transaction tx = session.beginTransaction(); //Item no estado Persistente Item item = (Item) session.load(Item. class , id); //Item no estado Removido session.delete(item); tx.commit(); //Item no estado Transiente session.close();
  169. 170. De Persistente para Transiente
  170. 171. Trabalhando com Objetos Desconectados <ul><li>Modificações realizadas em objetos Desconectados não são sincronizadas na base de dados </li></ul><ul><li>A atualização da base de dados pode ser feita de duas formas </li></ul><ul><ul><li>Reconectando o objeto – reattach </li></ul></ul><ul><ul><li>Realizando o merge do objeto </li></ul></ul>
  171. 172. Reconectando um Objeto <ul><li>Um objeto é reconectado através do método update() da interface Session </li></ul><ul><li>O objeto passa a ser gerenciado pelo Session e assume o estado Persistente </li></ul><ul><li>Deve-se ter certeza de que o Session ainda não possui um objeto gerenciado com o mesmo Id </li></ul><ul><ul><li>Somente uma instância do Contexto de Persistência pode estar associada a um determinado registro </li></ul></ul>
  172. 173. Reconectando um Objeto Item item = recuperarItem ( armazenarItem ()); item.setName( &quot;Novo nome&quot; ); Session session = HibernateUtil. getSessionFactory ().openSession(); Transaction transaction = session.beginTransaction(); session.update(item); item.setPrice(Integer. valueOf (114)); transaction.commit(); session.close();
  173. 174. Reconectando um Objeto
  174. 175. NonUniqueObjectException Long id = armazenarItem (); Item item = recuperarItem (id); item.setName( &quot;Novo nome&quot; ); Session session = HibernateUtil. getSessionFactory ().openSession(); Transaction transaction = session.beginTransaction(); Item item2 = (Item) session.get(Item. class , id); session.update(item); item.setPrice(Integer. valueOf (114)); transaction.commit(); session.close();
  175. 176. Realizando o merge() de um Objeto <ul><li>O merge de um objeto é feito através do método merge() da Interface Session </li></ul><ul><li>A a base de dados é atualizada com os valores contidos no objeto </li></ul><ul><li>Os dados do objeto também atualizam o objeto persistente que possuir o mesmo identificador </li></ul><ul><ul><li>Se não existir um objeto persistente associado ao Session, ele é carregado </li></ul></ul>
  176. 177. Método merge() <ul><li>O objeto desconectado não passa a ser associado ao Session </li></ul><ul><ul><li>Continua desconectado </li></ul></ul><ul><li>O objeto persistente é retornado </li></ul>
  177. 178. Método merge() Long id = armazenarItem (); Item item = recuperarItem (id); item.setName( &quot;Novo nome!!!&quot; ); Session session = HibernateUtil. getSessionFactory ().openSession(); Transaction transaction = session.beginTransaction(); Item item2 = (Item) session.get(Item. class , id); Item item3 = (Item) session.merge(item); transaction.commit(); session.close();
  178. 179. Método merge()
  179. 180. Persistência Transitiva <ul><li>Em aplicações não triviais, diversas Entidades podem estar associadas </li></ul><ul><li>A aplicação deve poder manipular as associações </li></ul><ul><li>Uma rede de objetos pode consistir de objetos em diferentes estados </li></ul><ul><ul><li>Persistentes </li></ul></ul><ul><ul><li>Desconectados </li></ul></ul><ul><ul><li>Transientes </li></ul></ul>
  180. 181. Persistência Transitiva <ul><li>A Persistência Transitiva permite persistir objetos Desconectados e Transientes automaticamente </li></ul><ul><li>Um objeto Transiente associado a um Persistente, torna-se persistente automaticamente </li></ul><ul><ul><li>Não há necessidade de chamar o método save() </li></ul></ul><ul><li>Diversas operações poder ser cascateadas </li></ul><ul><ul><li>Salvar </li></ul></ul><ul><ul><li>Deletar </li></ul></ul><ul><ul><li>Reconectar (update) </li></ul></ul><ul><ul><li>Merge </li></ul></ul>
  181. 182. Cascade <ul><li>Por default, em nenhuma operação é feito o cascade </li></ul><ul><li>O Hibernate permite a configuração do tipo de comportamento desejado para cada associação </li></ul><ul><li>Todos os tipos de associações podem ser configuradas </li></ul><ul><ul><li>one-to-one </li></ul></ul><ul><ul><li>one-many </li></ul></ul><ul><ul><li>many-to-many </li></ul></ul><ul><ul><li>many-to-one </li></ul></ul>
  182. 183. org.hibernate.annotations.CascadeType <ul><li>SAVE_UPDATE </li></ul><ul><ul><li>Objetos transientes são salvos </li></ul></ul><ul><ul><li>Objetos desconectados são sincronizados </li></ul></ul><ul><li>DELETE </li></ul><ul><ul><li>Objetos relacionados são deletados após a chamada do método delete() </li></ul></ul><ul><li>ALL </li></ul><ul><ul><li>Habilita todos os tipos de cascade </li></ul></ul>
  183. 184. org.hibernate.annotations.CascadeType <ul><li>DELETE_ORPHAN </li></ul><ul><ul><li>Deleta um objeto se ele for excluído da coleção </li></ul></ul><ul><ul><li>Aplicável somente para relacionamentos One-to-Many </li></ul></ul><ul><li>Cascade é aplicável somente para relacionamentos entre entidades </li></ul>
  184. 185. Exercício
  185. 186. Consultas <ul><li>Umas das partes mais interessantes do acesso a dados </li></ul><ul><li>Consultas complexas podem levar um bom tempo para serem escritas e podem ter considerável impacto na performance da aplicação </li></ul><ul><li>Consultas são escritas utilizando conceitos de orientação a objetos </li></ul><ul><ul><li>Objetos no lugar de tabelas </li></ul></ul><ul><ul><li>Propriedades no lugar de colunas </li></ul></ul><ul><li>Experiência em SQL não é desprezada </li></ul>
  186. 187. Consultas <ul><li>Podem ser feitas de três maneiras </li></ul><ul><ul><li>Hibernate Query Language (HQL) </li></ul></ul><ul><ul><li>Criteria API e Query by Example </li></ul></ul><ul><ul><li>Utilizando SQL </li></ul></ul>
  187. 188. Consultas: Exemplos // Através de HQL session.createQuery( &quot;from Category c where c.name like 'Laptop%'&quot; ); // Utilizando-se Criteria session.createCriteria(Category. class ).add( Restrictions. like ( &quot;name&quot; , &quot;Laptop%&quot; )); // Através de SQL session.createSQLQuery( &quot;select {c.*} from CATEGORY {c} where NAME like 'Laptop%'&quot; ) .addEntity( &quot;c&quot; , Category. class );
  188. 189. Consultas <ul><li>Envolve alguns passos </li></ul><ul><ul><li>Criar a consulta com as restrições necessárias </li></ul></ul><ul><ul><li>Adicionar parâmetros à consulta </li></ul></ul><ul><ul><li>Executar a consulta e recuperar o resultado </li></ul></ul><ul><ul><ul><li>A forma de execução da consulta e obtenção dos dados pode ser configurada </li></ul></ul></ul>
  189. 190. Criando a Consulta <ul><li>Objetos Query e Criteria são obtidos através do Session </li></ul><ul><ul><li>org.hibernate.Query </li></ul></ul><ul><ul><li>org.hibernate.Criteria </li></ul></ul>Query query = session.createQuery( &quot;from User&quot; ); Criteria criteria = session.createCriteria(User. class );
  190. 191. Adicionando Parâmetros à Consulta <ul><li>Parâmetros não devem ser adicionados na própria String da consulta </li></ul><ul><ul><li>&quot;from Item i where i.description like '&quot; + search + &quot;'&quot; </li></ul></ul><ul><li>Evita-se ataque do tipo SQL Injection </li></ul><ul><ul><li>foo' and callSomeStoredProcedure() and 'bar' = 'bar </li></ul></ul><ul><li>Parâmetros podem ser adicionados através de sua posição ou de seu nome </li></ul>
  191. 192. Adicionando Parâmetros pelo Nome <ul><li>Nome do parâmetro é precedido de “:” </li></ul><ul><li>O valores são adicionados através de métodos sets </li></ul>String queryString = &quot;from Item item where item.description like :search&quot; ; Query q = session.createQuery(queryString).setString( &quot;search&quot; , searchString); String queryString = &quot;from Item item&quot; + &quot; where item.description like :search&quot; + &quot; and item.date > :minDate&quot; ; Query q = session.createQuery(queryString).setString( &quot;search&quot; , searchString).setDate( &quot;minDate&quot; , mDate);
  192. 193. Adicionando Parâmetros pela Posição <ul><li>A consulta contém “?” para indicar a existência de alguma parâmetro </li></ul><ul><li>Os valores também são adicionado através de métodos sets </li></ul>String queryString = &quot;from Item item&quot; + &quot; where item.description like ?&quot; + &quot; and item.date > ?&quot; ; Query q = session.createQuery(queryString).setString(0, searchString).setDate(1, minDate);
  193. 194. Executando a Consulta <ul><li>Se mais de um objeto pode ser retornado, chama-se o método list() </li></ul><ul><ul><li>List list = query.list(); </li></ul></ul><ul><li>Se somente um objeto pode ser retornado, chama-se o método uniqueResult() </li></ul><ul><ul><li>User user = (User) query.uniqueResult(); </li></ul></ul><ul><ul><li>O método retorna null se nenhum objeto for encontrado </li></ul></ul><ul><ul><li>Se a consulta retornar mais de um objetos, a exceção NonUniqueResultException é lançada </li></ul></ul>
  194. 195. Executando a Consulta Query query = session.createQuery( &quot;from User&quot; ); List<User> list = query.list(); for (User user : list) { System. out .println(user.getName()); } Query query2 = session.createQuery( &quot;from User user where user.name =:name&quot; ).setString( &quot;name&quot; , &quot;SUNSP&quot; ); User user = (User) query2.uniqueResult(); System. out .println(user.getName());
  195. 196. Consultas Básicas <ul><li>A consulta mais simples tem somente a cláusula FROM </li></ul><ul><ul><li>“ from Item” </li></ul></ul><ul><li>Para se referenciar as propriedades de uma entidade, um ALIAS deve ser criado </li></ul><ul><ul><li>“ from Item as item” </li></ul></ul><ul><ul><li>“ from Item item” </li></ul></ul><ul><ul><ul><li>Palavra chave “as” é opcional </li></ul></ul></ul><ul><li>A consulta não é case-sensitive </li></ul><ul><ul><li>“ FROM Item AS item” também pode ser utilizada </li></ul></ul>
  196. 197. Consultas Polimórficas <ul><li>Consultas podem ser escritas utilizando polimorfismo </li></ul><ul><li>“ from BillingDetails” </li></ul><ul><ul><li>Retorna todas as entidades que herdam de BillingDetails </li></ul></ul><ul><ul><ul><li>CreditCard </li></ul></ul></ul><ul><ul><ul><li>BankAccount </li></ul></ul></ul><ul><li>A superclasse não precisa estar mapeada </li></ul><ul><ul><li>“ from java.lang.Object” </li></ul></ul><ul><ul><li>“ from java.io.Serializable” </li></ul></ul>
  197. 198. Restrições <ul><li>Geralmente não se quer trazer todo o conteúdo da tabela </li></ul><ul><li>Restrições devem ser adicionadas para restringir os objetos retornados </li></ul><ul><li>HQL também utiliza-se a cláusula WHERE </li></ul><ul><li>As restrições são feitas sobre propriedades da entidade </li></ul>
  198. 199. Restrições <ul><li>Literais e condições podem ser incluídos </li></ul><ul><ul><li>Utiliza-se aspas simples para literais do tipo String </li></ul></ul><ul><ul><li>“ from User u where u.email = 'foo@hibernate.org '” </li></ul></ul><ul><ul><li>“ from Item i where i.isActive = true” </li></ul></ul><ul><li>Comparações podem ser realizadas </li></ul><ul><ul><li>“ from Bid bid where bid.amount between 1 and 10” </li></ul></ul><ul><ul><li>“ from Bid bid where bid.amount > 100” </li></ul></ul><ul><ul><li>“ from User u where u.email in ('foo@bar', 'bar@foo')” </li></ul></ul>
  199. 200. <ul><li>Operador LIKE pode ser utilizado </li></ul><ul><ul><li>“ %” representa qualquer seqüência de caracteres </li></ul></ul><ul><ul><li>_ (Under_Score) representa qualquer caractere </li></ul></ul><ul><ul><li>“ from User u where u.firstname like 'G%'” </li></ul></ul><ul><ul><li>Negação pode ser utilizada </li></ul></ul><ul><ul><ul><li>“ from User u where u.firstname not like '%Foo B%'” </li></ul></ul></ul><ul><li>Operadores lógicos e parênteses </li></ul><ul><ul><li>“ from User user where user.firstname like 'G%' and user.lastname like 'K%'” </li></ul></ul>Comparações
  200. 201. Comparações <ul><li>Operadores lógicos e parênteses </li></ul><ul><ul><li>“ from User u where (u.firstname like 'G%' and u.lastname like 'K%' ) or u.email in ('foo@hibernate.org', 'bar@hibernate.org' )” </li></ul></ul><ul><li>Coleções </li></ul><ul><ul><li>&quot;from Item i where i.bids is not empty&quot; </li></ul></ul>
  201. 202. Comparações <ul><li>Funções podem ser chamadas a partir do HQL </li></ul><ul><ul><li>HQL permite a chamada de funções SQL na cláusula WHERE </li></ul></ul><ul><ul><li>Funções podem ser definidas pelo usuário </li></ul></ul><ul><ul><ul><li>Depende do suporte do banco de dados </li></ul></ul></ul><ul><ul><li>Funções UPPER() e LOWER() </li></ul></ul><ul><ul><ul><li>&quot;from User u where lower(u.email) = 'foo@hibernate.org '&quot; </li></ul></ul></ul><ul><ul><li>Função SIZE() </li></ul></ul><ul><ul><ul><li>from Item i where size(i.bids) > 3 </li></ul></ul></ul><ul><ul><li>E muitas outras... </li></ul></ul>
  202. 203. Comparações <ul><li>Outras funções </li></ul><ul><ul><li>CONCAT(s1, s2) </li></ul></ul><ul><ul><li>SUBSTRING(s, offset, length) </li></ul></ul><ul><ul><ul><li>Offset começa a partir de 1 </li></ul></ul></ul><ul><ul><li>TRIM( [[BOTH|LEADING|TRAILING] s) </li></ul></ul><ul><ul><ul><li>&quot;from Item i where TRIM(BOTH i.name) = 'Computador'&quot; </li></ul></ul></ul><ul><ul><li>LENGTH(s) </li></ul></ul><ul><ul><li>LOCATE(search, s, offset) </li></ul></ul><ul><ul><ul><li>Procura a localização de uma substring dentro de uma string </li></ul></ul></ul>
  203. 204. Comparações <ul><li>Outras funções </li></ul><ul><ul><li>CURRENT_DATE(), CURRENT_TIME(), CURRENT_TIMESTAMP() </li></ul></ul><ul><ul><ul><li>Valores retornados são referentes ao SGBD </li></ul></ul></ul><ul><ul><li>SECOND(d), MINUTE(d), HOUR(d), DAY(d), MONTH(d), YEAR(d) </li></ul></ul><ul><ul><ul><li>Extraem os valores de um argumento temporal </li></ul></ul></ul>
  204. 205. Ordenando o Resultado <ul><li>A Cláusula ORDER BY é utilizada para ordenar o resultado </li></ul><ul><ul><li>&quot;from User u order by u.name&quot; </li></ul></ul><ul><li>Ordem ascendente ou descendente </li></ul><ul><ul><li>Utiliza-se asc ou desc </li></ul></ul><ul><ul><li>from User u order by u.username desc </li></ul></ul><ul><li>Ordenando por mais de uma propriedade </li></ul><ul><ul><li>“ from User u order by u.lastname asc, u.firstname asc” </li></ul></ul>
  205. 206. Junções <ul><li>A habilidade de realizar junções é uma das principais forças do modelo relacional </li></ul><ul><li>Permite selecionar diferentes objetos associados e coleções em uma única consulta </li></ul>
  206. 207. Inner Join <ul><li>Contém somente os registros que estão relacionados com o outro lado da junção </li></ul><ul><ul><li>Contém somente os Itens que possuem Bids </li></ul></ul>
  207. 208. (left) Outer Join <ul><li>Retorna todos os Itens </li></ul><ul><ul><li>Dados de Bid são preenchidos com NULL se não houver uma correspondência </li></ul></ul>
  208. 209. Junção com HQL <ul><li>Coluna de junção não precisar ser informada na consulta </li></ul><ul><ul><li>Informação é extraída do mapeamento </li></ul></ul><ul><li>É necessário ser informado somente o nome da associação </li></ul><ul><ul><li>Nome do atributo que referencia a classe ou coleção de classes </li></ul></ul><ul><li>Joins podem ser executados de duas maneiras </li></ul><ul><ul><li>Join implícitos na Associação </li></ul></ul><ul><ul><li>Join especificado na cláusula FROM </li></ul></ul>
  209. 210. Join Implícito na Associação <ul><li>O Join é realizado através da associação entre duas entidades </li></ul><ul><li>Exemplo: </li></ul><ul><ul><li>“ from Bid bid where bid.item.description like '%Foo%'” </li></ul></ul><ul><ul><li>Bid é associado a Item através do atributo “item” </li></ul></ul><ul><ul><li>Hibernate sabe que a associação está mapeada a partir da chave estrangeira ITEM_ID da tabela BID </li></ul></ul><ul><li>Joins implícitos são sempre realizados através de associações many-to-one ou one-to-one </li></ul>
  210. 211. Join Implícito na Associação <ul><li>Múltiplos joins são possíveis </li></ul><ul><ul><li>from Bid bid where bid.item.category.name like 'Laptop%' </li></ul></ul>
  211. 212. Join especificado na Cláusula FROM <ul><li>Joins podem ser especificados explicitamente na cláusula FROM </li></ul><ul><li>Exemplo </li></ul><ul><ul><li>&quot;select i from Item i join i.bids b where b.amount > 10&quot; </li></ul></ul><ul><li>Aliases devem ser especificados na cláusula FROM e utilizados na cláusula WHERE </li></ul><ul><li>Cláusula SELECT é utilizada para que somente Itens sejam retornados </li></ul>
  212. 213. Join especificado na Cláusula FROM <ul><li>Na consulta, um Item pode ser retornado mais de uma vez </li></ul><ul><ul><li>Uma para cada Bid associado </li></ul></ul><ul><ul><li>Somente uma instância é utilizada </li></ul></ul><ul><li>A consulta possui o mesmo formato para associações many-to-one e one-to-one </li></ul>
  213. 214. Outer Joins <ul><li>Para a utilização de Outer Joins utiliza-se a cláusula LEFT JOIN </li></ul><ul><ul><li>LEFT OUTER JOIN e RIGHT OUTER JOIN também podem ser utilizados </li></ul></ul><ul><li>A cláusula WITH é utilizada para adicionar restrições </li></ul><ul><li>&quot;select i from Item i left join i.bids b with b.amount >= 9&quot; </li></ul><ul><ul><li>Itens que não possuem Bids também são retornados </li></ul></ul>
  214. 215. Comparando Identificadores <ul><li>Na Orientação a Objetos não são os identificadores, mas as referências ao objetos que são comparadas </li></ul><ul><li>Comparações podem ser feitas através dos atributos das entidades </li></ul><ul><li>&quot;select i from Item i join i.bids b where i.seller = b.bidder&quot; </li></ul><ul><ul><li>i.seller e b.bidder representam referências para a entidade User </li></ul></ul><ul><ul><li>Retorna os Itens em que o próprio vendedor deu um lance </li></ul></ul>
  215. 216. Comparando Identificadores <ul><li>Entidades também podem ser adicionadas como parâmetros de uma consulta </li></ul>Query query = session.createQuery( &quot;from Item i where i.seller = :seller&quot; ); query.setEntity( &quot;seller&quot; , user);
  216. 217. FIM... <ul><li>Referências </li></ul><ul><ul><li>Livro Java Persistence with Hibernate </li></ul></ul><ul><ul><ul><li>Edição revisada do livro Hibernate in Action </li></ul></ul></ul><ul><ul><ul><li>Autores </li></ul></ul></ul><ul><ul><ul><ul><li>Christian Bauer </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Gavin King </li></ul></ul></ul></ul><ul><ul><li>http://www.hibernate.org/ </li></ul></ul><ul><ul><ul><li>Documentação e Javadoc </li></ul></ul></ul><ul><ul><ul><li>Fórum de discuções e dúvidas </li></ul></ul></ul><ul><ul><li>JSR 220: Enterprise JavaBeans Version 3.0 </li></ul></ul><ul><ul><ul><li>Para as Annotations do pacote javax.persistence </li></ul></ul></ul>

×