Configuração de Relacionamentos com Hibernate (Um-Para-Muitos, Um-Para-Um e Muitos-Para-Muitos)

Primerio tipo de relacionamento: Um-Para-Muitos (Muitos-Para-Um)

O "um-para-muitos" é o mapeamento mais comum em sistemas de banco de dados, como o relacionamento entre clientes e pedidos.

Um-Para-Muitos: Do ponto de vista do cliente, um cliente pode ter vários pedidos, ou seja, um-para-muitos.

Muitos-Para-Um: Do ponto de vista dos pedidos, muitos pedidos podem pertencer a um único cliente, ou seja, muitos-para-um.

A configuração no arquivo hbm para o relacionamento um-para-muitos:

Cliente (lado "um"):

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping>
    <class name="br.exemplo.hibernate.entidades.Cliente" table="cliente">
        <!-- Configuração da chave primária -->
        <id name="id" type="string">
            <column name="id"/>
            <generator class="uuid"/>
        </id>
        <!-- Propriedades -->
        <property name="nome" column="nome" type="string"/>
        <property name="saldo" column="saldo" type="integer"/>

        <set name="pedidos" inverse="true" cascade="all">
            <key column="cliente_id"/>
            <one-to-many class="br.exemplo.hibernate.entidades.Pedido"/>
        </set>
    </class>
</hibernate-mapping>

Pedido (lado "muitos"):

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping>
    <class name="br.exemplo.hibernate.entidades.Pedido" table="pedido">
        <id name="id" type="string">
            <column name="id"/>
            <generator class="uuid"/>
        </id>

        <property name="numeroPedido" column="numero_pedido" type="string"/>
        <property name="valor" column="valor" type="integer"/>

        <many-to-one name="cliente" class="br.exemplo.hibernate.entidades.Cliente"
                     column="cliente_id" cascade="save-update"/>
    </class>
</hibernate-mapping>

O relacionamento um-para-muitos faz com que a entidade Cliente tenha uma coleção de Pedidos, enquanto Pedido possui uma referência ao Cliente associado.

Um caso especial de um-para-muitos é o relacionamento consigo mesmo. Por exemplo:

Configuração de auto-relacionamento um-para-muitos:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping>
    <class name="br.exemplo.hibernate.entidades.Categoria" table="categoria">
        <id name="id" type="string">
            <column name="id"/>
            <generator class="uuid"/>
        </id>

        <property name="descricao" column="descricao" type="string"/>

        <set name="subCategorias" cascade="all" inverse="true">
            <key column="categoria_pai_id"/>
            <one-to-many class="br.exemplo.hibernate.entidades.Categoria"/>
        </set>

        <many-to-one name="categoriaPai" class="br.exemplo.hibernate.entidades.Categoria" column="categoria_pai_id"/>
    </class>
</hibernate-mapping>

Aqui, a tabela Categoria tem uma coluna que armazena a chave primária da categoria pai.

Segundo tipo de relacionamento: Muitos-Para-Muitos

O relacionamento muitos-para-muitos ocorre quando duas entidades estão interligadsa bidirecionalmente. Por exemplo, alunos e disciplinas opcionais. Um aluno pode cursar várias disciplinas, e cada disciplina pode ser cursada por vários alunos. Este tipo de relacionamento geralmente usa uma tabela intermediária.

Exemplo de configuração no arquivo hbm:

Aluno:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping>
    <class name="br.exemplo.hibernate.entidades.Aluno" table="aluno">
        <id name="id" type="integer">
            <column name="id"/>
            <generator class="increment"/>
        </id>

        <property name="nomeAluno" column="nome" type="string"/>

        <set name="disciplinas" inverse="false" cascade="save-update" table="aluno_disciplina">
            <key column="aluno_id"/>
            <many-to-many class="br.exemplo.hibernate.entidades.Disciplina" column="disciplina_id"/>
        </set>
    </class>
</hibernate-mapping>

Disciplina:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping>
    <class name="br.exemplo.hibernate.entidades.Disciplina" table="disciplina">
        <id name="id" type="integer">
            <column name="id"/>
            <generator class="increment"/>
        </id>

        <property name="nomeDisciplina" column="nome" type="string"/>

        <set name="alunos" inverse="true" cascade="save-update" table="aluno_disciplina">
            <key column="disciplina_id"/>
            <many-to-many class="br.exemplo.hibernate.entidades.Aluno" column="aluno_id"/>
        </set>
    </class>
</hibernate-mapping>

O atributo "table" na tag <set> define a tabela intermediária usada para conectar as duas tabelas principais.

Terceiro tipo de relacionamento: Um-Para-Um

Relacionamentos um-para-um ocorrem quando uma única instância de uma entidade está vinculada a uma única instância de outra entidade. Por exemplo, um time esportivo pode estar associado a apenas um endereço.

Existem dois tipos principais de relacionamento um-para-um: baseado em chave estrangeira e baseado em chave primária.

Exemplo de configuração usando chave estrangeira:

Endereço:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping>
    <class name="br.exemplo.hibernate.entidades.Endereco" table="endereco">
        <id name="id" type="integer">
            <column name="id"/>
            <generator class="increment"/>
        </id>

        <property name="cidade" column="cidade" type="string"/>

        <one-to-one name="time" class="br.exemplo.hibernate.entidades.Time" cascade="all"/>
    </class>
</hibernate-mapping>

Time:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping>
    <class name="br.exemplo.hibernate.entidades.Time" table="time">
        <id name="id" type="integer">
            <column name="id"/>
            <generator class="increment"/>
        </id>

        <property name="nomeTime" column="nome" type="string"/>

        <many-to-one name="endereco" class="br.exemplo.hibernate.entidades.Endereco" column="endereco_id" unique="true"/>
    </class>
</hibernate-mapping>

No relacionamento um-para-um baseado em chave estrangeira, a anotação "unique=true" garante que cada registro no lado "muitos" esteja associado a apenas um registro no lado "um".

Configuração usando chave primária:

Endereço:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping>
    <class name="br.exemplo.hibernate.entidades.Endereco" table="endereco">
        <id name="id" type="integer">
            <column name="id"/>
            <generator class="increment"/>
        </id>

        <property name="cidade" column="cidade" type="string"/>

        <one-to-one name="time" class="br.exemplo.hibernate.entidades.Time" cascade="all"/>
    </class>
</hibernate-mapping>

Time:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping>
    <class name="br.exemplo.hibernate.entidades.Time" table="time">
        <id name="id" type="integer">
            <column name="id"/>
            <generator class="foreign">
                <param name="property">endereco</param>
            </generator>
        </id>

        <property name="nomeTime" column="nome" type="string"/>

        <one-to-one name="endereco" class="br.exemplo.hibernate.entidades.Endereco" cascade="all"/>
    </class>
</hibernate-mapping>

Neste caso, a chave primária da tabela Time é gerada com base na chave primária da tabela Endereço.

Tags: hibernate java ORM

Publicado em 8-8 01:08