Anterior Próximo

Heranca com Nhibernatepublicado em 22/03/2010

Como sabemos, a herança é o conceito que permite que uma classe compartilhe seus atributos e comportamentos com as classes que a extendem.

o Nhibernate possui diversas maneiras de mapear este conceito, falarei aqui de 2 delas:

  • Table per class hierarchy
  • Table per subclass

Dado o modelo abaixo, mostrarei como ficará o mapeamento em cada uma dessas maneiras:

Diagrama de classe

Table per class hierarchy - Este modelo necessitará de apenas uma tabela no banco de dados pois o nhibernate perceberá a diferença entre uma classe e outra através do campo discriminator. Como você já deve imaginar esta forma acaba por gerar alguns atributos nulos na base de dados dependendo da entidade a ser gravada, por este motivo nenhum campo das subclasses pode ser marcado como not-null.

<class abstract="true" table="tb_animal" name="Animal">
    <id name="Id" column="id" type="String" length="32">
        <generator class="uuid.hex"/>
    </id>

    <discriminator column="tipo" not-null="true"></discriminator>

    <property column="nome" name="Nome" type="String" length="200" not-null="true"></property>
    <property column="nome" name="Peso" type="Decimal" not-null="true"></property>

    <subclass name="Cachorro" discriminator-value="cachorro">
        <property column="melhor_amigo" name="MelhorAmigo" type="Boolean"></property>
    </subclass>

    <subclass name="Gato" discriminator-value="gato">
        <property column="numero_de_vidas" name="NumeroDeVidas" type="Int32"></property>
    </subclass>        
</class>

Com a ajuda do SchemaExport do Nhibernate criei a database a partir do mapeamento ( isso é assunto para outro post ) a cima e a tabela resultante ficou da seguinte forma:

Banco de dados

Para que entendam a finalidade do campo discriminator, fiz a inclusão de um gato e de um cachorro na base de dados, repare que campo "tipo" é preenchido automaticamente pelo Nhibernate com os valores definidos no mapeamento.

Banco de dados

Table per subclass - Nesta forma, nosso modelo necessitará de 3 tabelas, uma tabela para cada classe e não tem a restrição dos campos não poderem ser not-null.

<class abstract="true" table="tb_animal" name="Animal">
    <id name="Id" column="id_animal" type="String" length="32">
        <generator class="uuid.hex"/>
    </id>
    
    <property column="nome" name="Nome" type="String" length="200" not-null="true"></property>
    <property column="peso" name="Peso" type="Decimal" not-null="true"></property>

    <joined-subclass name="Cachorro" table="tb_cachorro">
        <key column="id_animal"></key>
        <property column="melhor_amigo" name="MelhorAmigo" type="Boolean"></property>
    </joined-subclass>

    <joined-subclass name="Gato" table="tb_gato">
        <key column="id_animal"></key>
        <property column="numero_de_vidas" name="NumeroDeVidas" type="Int32"></property>
    </joined-subclass>       
</class>

Banco de dados

Repare que agora tempos 3 tabelas e que o NH se encarrega de separar os dados em cada uma delas.

Banco de dados

Além dessas maneiras que descrevi aqui a documentação do Nhibernate cita pelo menos mais 3 outras diferentes e não menos importantes. Todas elas podem ser encontradas aqui

Você pode fazer o download dos 2 exemplos aqui.


Tags:

retweet

BBCode permitido - [code], [pre], [b], [i], [u], [del], [url], [left], [right], [center]

  • 23/3/2010 23:15 - Tiago Ervatti

    Boa Diogo, gostando de ver se aprofundando no NH, Muito bom.
    Lembra dos primeiros passos?? "Tiago, to achando isso muito confuso, to gostando não". Hoje em dia ta dominando, não dominado, parabéns pelos artigos. Grande abraço.


Ir direto para o topo