Classes #

No diagrama de classes, algumas classes são persistentes e outras não. As classes persistentes que pertencem a uma hierarquia de herança devem ser mapeadas de acordo com as opções descritas no item ComposiçãoCada classe persistente restante, de uma forma geral, se transforma em uma tabela. O nome da tabela deve seguir os padrões de nomenclatura do apêndice Padrões de Nomenclatura

Atributos #

O modelo relacional não trata a visibilidade dos atributos. Todos os atributos são públicos. De uma maneira geral, cada atributo de classe se transforma numa coluna da tabela correspondente. A seguir são analisados casos específicos:Para os atributos mono-valorados composto cria-se uma coluna na tabela base para cada um dos componentes do atributo composto.Para os atributos multi-valorados, cria-se uma nova tabela para cada atributo multi-valorado, que possui uma Chave Primária herdada da tabela base (estrangeira).

Deve-se analisar os atributos que obrigatoriamente não podem receber valores nulos e identifica-los no diagrama. Entre os atributos da classe, deve-se identificar a chave primária ou criar um atributo para este fim.

Enumerações #

As classes enumeration serão tratadas em código pelo hibernate. Para cada classe que tenha relacionamento com a enumeração deve-se acrescentar uma coluna que armazene o código da enumeração (normalmente do tipo inteiro).

Associações simples #

As associações geram a migração da chave primária de uma tabela para a tabela associada, formando uma chave estrangeira. Se a associação define uma dependência existencial, a chave estrangeira deve compor a chave primária da tabela associada.

Associações 1-para-1 ou 0..1-para-1 #

Recomendado:

  • Manter apenas uma relação contendo os atributos e relacionamentos das duas classes.
    • Alternativo:
  • Mapear uma relação para cada classe.
  • Cardinalidade 0..1: Embutir a chave estrangeira na classe com cardinalidade 0..1.
  • Cardinalidade 1-1: Embutir a chave estrangeira em qualquer uma das classes (tabelas), que neste caso será necessariamente NOT NULL.

Vantagens: O esquema se torna mais extensível. Se houver mudança na cardinalidade não é necessário mudar a estrutura das tabelas.

Desvantagens: fragmentação do esquema e maior overhead de navegação (com joins)

Associações 1-para-muitos ou 0..1-para-muitos #

Recomendado:

  • Embutir a chave estrangeira na classe com cardinalidade "muitos"
  • Se a cardinalidade do alvo puder ser 0, a chave estrangeira pode ser nula
    • Alternativo:
  • A associação pode ser implementada numa tabela à parte.
  • Mesmas vantagens e desvantagens do mapeamento 1-para-1

Associações muitos-para-muitos #

  • A associação é mapeada para uma tabela distinta
  • A chave primária da tabela de associação é uma combinação das chaves estrangeiras.

Herança (generalização) #

Existem várias opções de mapeamento:

  1. Mapear a superclasse e as subclasses em uma única relação;
  2. Mapear cada subclasse em sua própria relação, junto com seus respectivos atributos genéricos.
  3. Mapear a superclasse e as subclasses em relações diferentes;

Para facilitar o mapeamento é necessário identificar/criar um atributo que distingue os objetos de cada subclasse (atributo discriminador) e classificar o tipo de herança segundo os seguintes critérios:

Mutuamente exclusivo: Se um objeto da superclasse pertence a uma categoria representada por apenas uma subclasse. Com sobreposição: Se um objeto da superclasse pode pertencer a categorias representadas por mais que uma subclasse.Participação Total: Todos os objetos da superclasse pertencentes a pelo menos uma categoria representada por alguma subclasse.

Superclasse e as subclasses em uma única relação #

Quando não utilizar:

  • Quando existir sobreposição.
  • Quando as subclasses diferem não apenas pelo comportamento, pois possuem muitos atributos específicos.

Como mapear:

  • Cria-se uma unica relação contendo os atributos da superclasse, o atributo discriminador e os atributos das subclasses. A chave da relação será a chave da superclasse.

Considerações gerais:

  • Se todo objeto da superclasse poderá ser instanciado como objeto de alguma subclasse (participação total), o atributo discriminador deverá ser NOT NULL.
  • Em cada tupla apenas os atributos correspondentes à subclasse podem possuir valor, os atributos correspondentes às demais subclasses devem ser mantidos nulos. Observe que há uma perda da gerência de integridade de dados pelo banco.

Cada subclasse em sua própria relação #

Quando não utilizar:

  • Quando houver necessidade freqüente de acessar informações envolvendo todas as entidades genéricas
  • Quando existir associações com a superclasse
  • Quando não existir participação total das subclasses.

Como mapear:

  • Cria-se uma relação para cada subclasse contendo os atributos da superclasse e os atributos das subclasses. A chave da relação será a chave da superclasse.

Considerações gerais:

  • Para obter todas as entidades que representam a superclasse é necessário executar a união de todos as relações que mapeiam as subclasses.
  • As associações da superclasse devem ser mapeadas para cada relação gerada a partir das subclasses.
  • Este procedimento não garante exclusão mútua.

Considerações – Hibernate:

  • O Hibernate não suporta o uso de UNION, para obter todas as entidades que representam a superclasse serão geradas múltiplas consultas SQL.

Superclasse e as subclasses em relações diferentes #

Quando utilizar:

  • Quando existir associações com a superclasse
  • Existem poucas subclasses, cada uma com diversos atributos específicos.
  • As consultas tipicamente se concentram na superclasse ou em poucas subclasses.

Mutuamente exclusivas

O atributo discriminador deverá fazer parte da relação que representa a superclasse, garantindo que receberá somente um valor. Como mapear:

  • Cria-se uma relação para a superclasse que inclui o atributo discriminador.
  • Cria-se uma relação para cada subclasse, cuja chave da relação é o mesmo atributo da superclasse.

Considerações gerais:

  • Se há participação total o atributo discriminador deverá ser NOT NULL.

Existe sobreposição

Como mapear:

  • Cria-se uma relação para a superclasse;
  • Cria-se uma relação para cada subclasse, cuja chave da relação é o mesmo atributo da superclasse.

Considerações gerais:

  • Não poderá ser garantida a participação total dos objetos da superclasse na herança.
  • Neste caso, verificar se uma entidade tem determinado subtipo implica em verificar se ela existe na relação que mapeia esse subtipo. Para facilitar a consulta pode-se criar uma relação separada contendo apenas a chave primária formada pelo atributo discriminador e chave da superclasse.

Agregação #

Exitem duas opções para mapeamento:

  • Uma única relação para classe agregadora e classe agregada
  • Uma relação para a classe agregadora e outra para classe agregada. A tabela da classe agregadora deve possuir a identificação do objeto agregado implementado através de uma chave estrangeira. Como o objeto parte não existe sem o objeto todo, a chave estrangeira fará parte da chave primária formando um relacionamento identificador.

Considerações – Hibernate

  • Nas relações com chave primária composta, deve-se analisar se o acesso direto à relação pode ser facilitada pela criação de uma chave incremental.

Composição #

Mesmas opções de mapeamento da Agregação.

Abstração da herança, agregação e composição #

Numa herança, é possível criar uma View para cada relação que representa as subclasses, no sentido de consolidar os dados herdados e facilitar o acesso ao objeto. A mesma abstração pode ser utilizada para agregações e composições. Exemplo: CREATE VIEW VIEW_SUPERCLASSE ASSELECT A.ID_SUPERCLASSE, ATRIBUTO_SUBCLASSE, ATRIBUTO_SUPERCLASSEFROM SUPERCLASSE AS A JOIN SUBCLASSE AS B ON A.ID_SUPERCLASSE = B.ID_SUPERCLASSE

Operações #

Um SGBD Relacional não permite encapsular operações (métodos) com classes, mas oferece meios de colocar alguma funcionalidade dos métodos no SGBD.A implementação de stored procedures pode contribuir para particionar o código entre o servidor de BD e as outras camadas da aplicação. As regras a seguir analisam quais funcionalidades são adequadas ou não para serem implementadas em stores procedures.

O que evitar:

  • colocar operações que lidam com aspectos transientes no SGBD;
  • grandes quantidades de verificação de erro, com condições de aborto, etc;
  • fazer ações transacionais (COMMIT, ROLLBACK) em stored procedures.

O que pode ser colocado no SGBD:

  • Consultas comuns dando um result set (um conjunto de registros)
  • Verificação de regras de consistência
  • Verificação de erros relacionados com a estrutura do BD