Mapeando Coleções com Hibernatepor: Raphaela Galhardo (raphaela@jeebrasil.com.br) Este tutorial apresenta o mapeamento de coleções usando o Hibernate. IntroduçãoO mapeamento de coleções já foi apresentado nos tutoriais sobre associações. Essa seção está destinada a apresentar o mapeamento dos quatro tipos de coleções existentes: Set, Bag, List e Map. SetUm Set é um conjunto que contém elementos únicos. Como já citado, o seu mapeamento é feito através da tag set e possui o conjunto de atributos mostrado na Listagem 1. Esses atributos são semelhantes para os demais tipos de coleções a serem apresentadas. <set name="nomePropriedade” table="nomeTabela" schema="nomeEsquema" lazy="true|false" inverse="true|false" cascade="all|delete|save-update|delete|delete-orphan|all-delete- orphan" sort="unsorted|natural|comparatorClass" order-by="nome_coluna asc|desc" where="condição sql arbitrária"> <key .../> <element .../> | <one-to-many .../> | <many-to-many .../> </set> Listagem 1 - - Coleções: Atributos Dos atributos ainda não apresentados nos tutoriais sobre associações estão:
Exemplos de Set já foram apresentados nos mapeamentos dos relacionamentos. Para exemplificar o mapeamento de um Set de tipos primitivos considere o mapeamento de uma coleção de String’s para armazenar os telefones de um Aluno, como visto na Figura 1. Então no mapeamento Aluno.hbm.xml deve ser inserido o mapeamento mostrado na Listagem 2.
Figura 1 - Coleção de telefones para Aluno ... <set name="telefones" lazy="true" table="ALUNO_TELEFONE"> <key column="ID_ALUNO"/> <element type="java.lang.String" column="TELEFONE" not-null="true"/> </set> ... Listagem 2 - Coleções: Set Os telefones do aluno são armazenados na tabela ALUNO_TELEFONE. Para o banco de dados está tabela é separada da tabela ALUNO, mas para o Hibernate, ele cria a ilusão de uma única entidade. A tag key indica a chave estrangeira da entidade pai (ID_ALUNO). A tag element indica o tipo da coleção (String) e a coluna na qual está a informação. Um Set não pode apresentar elementos duplicados, portanto a chave primária de ALUNO_TELEFONE consiste nas colunas ID_ALUNO e TELEFONE. Dado o mapeamento da coleção de telefones de Aluno, observe o exemplo mostrado na Listagem 3. Neste exemplo, cria-se um objeto Aluno que terá o seu nome definido e um único número de telefone inserido em sua coleção de String’s. Por fim, o objeto Aluno é persistido. O resultado é mostrado na Listagem 4, onde primeiro é inserida uma linha na tabela ALUNO e posteriormente uma linha na tabela ALUNO_TELEFONE. Aluno aluno = new Aluno(); aluno.setNome("João Maria Costa Neto"); aluno.setTelefones(new HashSet Listagem 3 - Exemplo de Mapeamento de Set Hibernate: insert into ALUNO (MATRICULA, NOME, CPF, ID_CURSO, ID_ALUNO) values (?, ?, ?, ?, ?) Hibernate: insert into ALUNO_TELEFONE (ID_ALUNO, TELEFONE) values (?, ?) Listagem 4 - Resultado da execução do código presente na Listagem 3 ListUm List é uma coleção ordenada que pode conter elementos duplicados. O mapeamento de uma lista requer a inclusão de uma coluna de índice na tabela do banco de dados. A coluna índice define a posição do elemento na coleção, como visto na Figura 2 no mapeamento da coleção de telefones da entidade Aluno como sendo um List. Dessa maneira, o Hibernate pode preservar a ordenação da coleção quando recuperada do banco de dados e for mapeada como um List. Observe o mapeamento da coleção telefones na Listagem 5.
Figura 2 - Coleção de telefones para Aluno: List ... <list name="telefones" lazy="true" table="ALUNO_TELEFONE"> <key column="ID_ALUNO"/> <index column="POSICAO"/> <element type="java.lang.String" column="TELEFONE" not-null="true"/> </list > ... Listagem 5 – Coleções: List Mapeando a coleção como um List, a chave primária da tabela ALUNO_TELEFONE passa a ser as colunas ID_ALUNO e POSICAO, permitindo a presença de telefones (TELEFONE) duplicados na coleção. MapsMaps associam chaves aos valores e não podem conter chaves duplicadas. Eles diferem de Sets no fato de que Maps contêm chaves e valores, ao passo que Sets contêm somente a chave. O mapeamento de um Map é semelhante ao de um List, onde o índice de posição passa a ser a chave. Veja a Figura 3. A Listagem 6 apresenta a coleção de telefones sendo mapeada como um Map. A chave primária da tabela ALUNO_TELEFONE passa a ser as colunas ID_ALUNO e CHAVE, também permitindo a presença de telefones duplicados na coleção.
Figura 3 - Coleção de telefones para Aluno: Map ... <map name="telefones" lazy="true" table="ALUNO_TELEFONE"> <key column="ID_ALUNO"/> <index column="CHAVE" type="java.lang.String"/> <element type="java.lang.String" column="TELEFONE" not-null="true"/> </map> ... Listagem 6 – Coleções: Map BagUm Bag consiste em uma coleção desordenada que permite elementos duplicados. Em Java não há implementação de um Bag, contudo o Hibernate fornece um mecanismo de que um List em Java simule o comportamento de um Bag. Pela definição de um List, uma lista é uma coleção ordenada, contudo o Hibernate não preserva a ordenação quando um List é persistido com a semântica de um Bag. Para usar o Bag, a coleção de telefones deve ser definida com o tipo List. Um exemplo de mapeamento de um Bag pode ser visto na Figura 4 e Listagem 7.
Figura 4 - Coleção de telefones para Aluno: Bag Para simular o Bag como List, a chave primária não deve ter associação com a posição do elemento na tabela, assim ao invés da tag index, utiliza-se a tag collection-id, onde uma chave substituta diferente é atribuída a cada linha da tabela na coleção. Entretanto, o Hibernate não fornece nenhum mecanismo para descobrir o valor chave substituta de uma linha em particular. ... <idbag name="telefones" lazy="true" table="ALUNO_TELEFONE"> <collection-id type="long" column="ID_ALUNO_TELEFONE"> <generator class="sequence"/> </collection-id> <key column="ID_ALUNO"/> <element type="java.lang.String" column="TELEFONE" not-null="true"/> </idbag> ... Listagem 7 - Coleções: Bag ConclusõesNeste tutorial foram apresentados os mapeamentos de coleções (Bag, Map, List, Set) usando o Hibernate. No próximo tutorial será apresentado o mapeamento de herança utilizando três estratégias distintas: tabela por classe concreta, tabela por hierarquia, tabela por sub-classe. Neste tutorial foram apresentados os mapeamentos de coleções. O próximo tutorial trará o mapeamento de herança, abordando três estratégias distintas. Referências
|