Hibernate – componentes, herança, e associações Jobson Ronan {[email protected]}

of 38 /38
Hibernate – componentes, herança, e associações Jobson Ronan {[email protected]}

Embed Size (px)

Transcript of Hibernate – componentes, herança, e associações Jobson Ronan {[email protected]}

  • Hibernate componentes, herana, e associaesJobson Ronan {[email protected]}

  • ObjetivosAprender como realizar o mapeamento de modelos entidades que possuem associaes, composies e herana com o hibernate

  • Granularidade alta (fina)Fine-grained == mais classes que tabelasMais coeso, mais reuso, modelo fcil de entenderFreqentemente o melhor modelo de dados para uma tabela traduz-se em mais de uma classeConsidere, por exemplo, uma tabela cliente com dois endereos: endereco_fatura e endereco_entrega, cidade_fatura, cidade_entrega, etc.Uma classe Endereco, agruparia campos relativos ao endereo de um Cliente, que teria propriedades enderecoFatura e enderecoEntrega como referncias para dois objetos da classe EnderecoUma coluna email poderia ser expandida em uma classe Email, para detalhar um tipo de dados e encapsular validao de e-mail em vez de ser uma mera propriedade String do Cliente

  • Tipos de objetos: entidade ou valorUm objeto do tipo entidade tem sua prpria identidade de registro de banco de dadosUma referncia para uma entidade tornada persistente como uma referncia no banco de dados (foreign key)Uma entidade pode existir independentemente de outra entidadeUm objeto do tipo valor no tem identidade de banco de dadosPertence a uma entidadeSeu estado persistente parte do registro da entidade que a possuiNo tm identificadores ou propriedades de identificaoO tempo de vida limitado pelo tempo de vida da entidade que o possuiExemplos nativos: Strings, Integers, etc.Um dos objetos de um registro tem uma identidade prpria; os outros so dependentes deleNo exemplo anterior: objetos do tipo Cliente so entidades, objetos do tipo Endereco e Email so valores dependentes de um Cliente

  • ComponentesUm componente em Hibernate a parte dependente de um objeto composto entidade-valorUma composio ocorre quando uma entidade, que tem identidade na tabela, est associada a objetos de valor que no tm identidade na tabela (seus dados so parte da tabela)A remoo do registro no banco remove a entidade e seus componentes derivados (no confunda com cascade-delete)Um componente uma propriedadeMeio termo entre uma propriedade de campo de dados (field) e uma propriedade que referncia em relacionamentoComponentes s existem como objetos, mas no como tabelasNo confunda com componente de software (arquitetura)

  • Componentes e tabelasOs atributos do componente esto mapeados mesma tabela que a classe composta

  • Mapeamento de componentes ...

  • Limitaes de componentesClasses mapeadas como componentes tm vrias limitaesNo podem ter seus objetos compartilhados (no h como referir-se a eles pois no tm identidade prpria)No existe maneira elegante de representar uma referncia nula para um componente ( representado com valores nulos em todas as colunas do componente): se voc gravar um componente no nulo com apenas valores nulos, Hibernate retorna null!

  • Mapeamento de heranaHerana o descasamento mais visvel entre os mundos relacional e orientado a objetosMundo OO possui relacionamento um e tem umMundo relacional apenas possui relacionamento tem umH vrias estratgias [Ambler 2002]*Uma tabela por classe concreta: modelo relacional ignora herana e polimorfismoUma tabela por hierarquia de classes: permite polimorfismo com tabelas de-normalizadas mais uma coluna extra contendo informao de tipoUma tabela por subclasse: representa relacionamentos um atravs de relacionamentos tem um (chave estrangeira)

  • Uma tabela por classe concreta

  • Uma tabela por classe concretaIdeal para classes que no fazem parte de uma hierarquia ou que esto na raiz de uma hierarquia (nvel mais alto)Essas classes no devem ser usadas em polimorfismoUma declarao para cada classe concreta; um atributo table diferente para cada uma (igual a mapeamento simples)DesvantagensPouco suporte para associaes polimrficasQueries polimrficos, executados em superclasses das classes usadas causam mltiplos queries nas tabelas mapeadas s classes concretasDificulta evoluo do esquema (mudanas semnticas em propriedades da superclasse afetam colunas de vrias tabelas)

  • Queries geradosOs queries abaixo so conceituais (o SQL real gerado pelo Hibernate pode ser diferente)Dois queries para fazer uma pesquisa na superclasse BillingDetails (ineficiente!)select CREDIT_CARD_ID, OWNER, NUMBER, CREATED, TYPE, ... from CREDIT_CARD where CREATED = ? select BANK_ACCOUNT_ID, OWNER, NUMBER, CREATED, BANK_NAME, ... from BANK_ACCOUNT where CREATED=?Para fazer uma pesquisa numa classe concretaselect CREDIT_CARD_ID, TYPE, EXP_MONTH, EXP_YEAR from CREDIT_CARD where CREATED = ?

  • Uma tabela por hierarquia

  • Uma tabela por hierarquiaMapeia-se a hierarquia toda a uma nica tabelaTabela inclui uma coluna para identificar a classe (tipo); esta coluna (discriminator) no mapeada a uma propriedade mas usada internamente pelo HibernateH colunas para todas as propriedades de todas as classes da hierarquiaA classe raiz mapeada da forma convencional Subclasses so mapeadas dentro de como VantagensForma mais eficiente de implementar polimorfismo simples de implementar, entender e evoluirDesvantagensColunas de propriedades declaradas em subclasses precisam aceitar valores nulos (no pode ser declarada not-null)

  • Queries geradosExemplo de query polimrfico (conceitual) na superclasse; um s query recupera dados de todas as subclassesselect BILLING_DETAILS_ID, BILLING_DETAILS_TYPE, OWNER, ..., CREDIT_CARD_TYPE, from BILLING_DETAILS where CREATED = ?Exemplo de um query em uma classe concretaselect BILLING_DETAILS_ID, CREDIT_CARD_TYPE, CREDIT_CARD_EXP_MONTH, ... from BILLING_DETAILS where BILLING_DETAILS_TYPE='CC' and CREATED = ?

  • Mapeamento

    ...

    ... ...

  • Uma tabela por subclasse

  • Uma tabela por subclasseRepresenta herana como relacionamentos de chave estrangeiraCada subclasse que declara propriedades persistentes (inclusive interfaces e classes abstratas) tem sua prpria tabelaCada tabela possui colunas apenas para propriedades no-herdadas, e uma chave primria que chave estrangeira da superclasseCriao de uma instncia cria registros nas tabelas da superclasse e subclasseA recuperao dos dados realizada atravs de um join das tabelas (que pode conter outros elementos ) pode ser usada no lugar de ou dentro de

  • Uma tabela por subclasseVantagensModelo relacional normalizadoEvoluo e restries de integridade simplesNovas classes/tabelas criadas sem afetar classes/tabelas existentesDesvantagensPerformance baixa em hierarquias complexasMais difcil de codificar a mo (complicado de integrar com JDBC legado)

  • Queries (conceituais) produzidosBem mais complicados...Query na superclasseselect BD.BILLING_DETAILS_ID, BD.CREATED, CC.TYPE, ..., BA.BANK_SWIFT, ... case when CC.CREDIT_CARD_ID is not null then 1 when BA.BANK_ACCOUNT_ID is not null then 2 when BD.BILLING_DETAILS_ID is not null then 0end as TYPEfrom BILLING_DETAILS BD left join CREDIT_CARD CC on BD.BILLING_DETAILS_ID = CC.CREDIT_CARD_ID left join BANK_ACCOUNT BA on BD.BILLING_DETAILS_ID = BA.BANK_ACCOUNT_IDwhere BD.CREATED = ?Query na subclasseselect BD.BILLING_DETAILS_ID, BD.CREATED, CC.TYPE, ... from CREDIT_CARD CC inner join BILLING_DETAILS BD on BD.BILLING_DETAILS_ID = CC.CREDIT_CARD_IDwhere CC.CREATED = ?

  • Qual estratgia?Normalmente, usa-se uma combinao de estratgiasEstratgias assumem desenvolvimento top-down (isto no integrao de um sistema legado)Se no houver necessidade de queries polimrficos ou associaes, prefira Tabela por Classe ConcretaSe houver necessidade de associaes polimrficas, use...... Tabela por Hierarquia se as classes tiverem poucas propriedades e for uma hierarquia simples... Tabela por Subclasse se a hierarquia for mais complicada ou classes tiverem muitas propriedades (ou ainda se as restries de Tabela por Hierarquia como nulidade de colunas forem inaceitveis no modelo de dados)

  • Resumo: tags de mapeamento

    Uma composio (objeto associado dependente)

    Usada para implementar a estratgia de mapeamento de herana tabela por hierarquia de classe

    Usado para implementar a estratgia table-per-subclass onde cada subclasse tem sua prpria tabela

    Coluna e propriedade usada na estratgia tabela por hierarquia de classe para identificar a subclasse

  • XML de mapeamento

  • AssociaesAssociaes no Hibernate funcionam da mesma maneira que associaes de objetos em JavaDiferente de EJBs CMP, onde relacionamentos so gerenciados pelo containerAssociaes de objetos em Hibernate so unidirecionais e no so gerenciadas pelo containerAssociaes sempre so relacionamentos entre entidadesAlgumas so implementadas via coleesAssociaes um-para-muitos so as mais comunsQualquer associao muitos-para-muitos pode ser implementada com um par de associaes um-para-muitos: mais simples!D para realizar quase tudo apenas com

  • Multiplicidade de associaesA primeira classificao que fazemos de uma associao sua multiplicidadeExemploH mais de um Lance (Bid) para um certo Item?H mais de um Item para um certo Lance?

    ConclusoExiste uma associao de muitos para um de Bid para ItemPor ser bidirecional, podemos dizer que tambm existe uma associao de um para muitos de Item para Bid: o item conhece todos os lances feitos para ele.

  • Uma simples associaoA associao unidirecional, muitos para um de Bid para Item a mais simples possvelA referncia retornada por Bid.getItem() mapeada coluna ITEM_ID na tabela BID, que chave estrangeira da chave primria da tabela ITEM

    public class Bid { ... private Item item; public void setItem(Item item) { this.item = item; } public Item getItem() { return item; } ... }

    ... Se houver um lance (bid) o item tem que existir

  • Many-to-one uma associao comumO modelo relacional many-to-oneUma referncia de objeto many-to-oneAlguns atributos:name e column: nome da propriedade e coluna do bancocascade: pode ter save-update, delete, all (informa que tipo de operao ser repetida no objeto da associao)outer-join: se true, objeto associado carregado junto com o objeto pai; se ausente, o comportamento ocorre se objeto associado no estiver definido como um proxy.

  • Tornando-a bidirecionalComo encontrar todos os lances para um dado item?Associao bidirecional um para muitos: use um set!

    public class Item { ... private Set bids = new HashSet(); public void setBids(Set bids) { this.bids = bids; } public Set getBids() { return bids; } public void addBid(Bid bid) { bid.setItem(this); bids.add(bid); }...} ...

  • Este contm : uma coleo de registros mapeado diretamente tabela!Representa uma relao um para muitos no modelo relacionalMapeamento direto: atributo class informa a classe (no preciso informar colunas nem nome da tabela o mapeamento da classe referida j tem essa informao!)

  • Um para umUma associao um para um pode ser declarada com o elemento e/ou H dois tipos de relacionamentos um-para-umAssociaes de chave estrangeira unvocas: a chave nunca se repete na classe associada usa elemento ; usa tambm se for bidirecional.Associaes de chave primria: os dois objetos compartilham a mesma chave primria usa apenas elementos

  • Associao muitos para muitos unidirecional ... Transaction tx = session.beginTransaction();

    Category cat = (Category) session.get(Category.class, categoryId); Item item = (Item) session.get(Item.class, itemId); cat.getItems().add(item);

    tx.commit();

  • Muitos para muitos bidirecional

    ...

    ...

  • Uso da associao bidirecional preciso modificar os dois lados!Transaction tx = session.beginTransaction(); Category cat = (Category) session.get(Category.class, categoryId); Item item = (Item) session.get(Item.class, itemId); cat.getItems().add(item);item.getCategories().add(category);tx.commit();

  • Associaes polimrficasTodas as associaes mostradas at agora suportam polimorfismoNo preciso fazer nada de especial para ter polimorfismo no Hibernate

  • Colees polimrficas: exemplo

    ... CreditCard cc = new CreditCard();cc.setNumber(ccNumber);cc.setType(ccType);cc.setExpiryDate(ccExpiryDate);

    Session s = f.openSession();Transaction tx = s.beginTransaction();

    User user = (User) s.get(User.class, uid);// Call convenience methoduser.addBillingDetails(cc);

    tx.commit(); s.close();Session s = f.openSession();Transaction tx = s.beginTransaction();User user = (User) s.get(User.class, uid);Iterator i = user.getBillingDetails().iterator();while ( i.hasNext() ) { BillingDetails bd = (BillingDetails) i.next(); // CreditCard.pay() or BankAccount.pay() bd.pay(ccPaymentAmount);}tx.commit(); s.close();

  • ConclusesHibernate no ajuda s na implementao de modelos simplesHibernate implementa facilmente coisas que levariam semanasAssociaes, composies e heranas no so mais problemas para a camada de persistncia

  • RefernciasHibernate in ActionHibernate reference manualcaveatemptor.hibernate.org

  • Exerccio 1Implementar no Hibernate o seguinte modelo