Hibernate.orgCommunity Documentation

Capítulo 27. Melhores práticas

Escreva classes compactas e mapeie-as usando <component>:

Use uma classe Endereço para encapsular rua, bairro, estado, CEP. Isto promove a reutilização de código e simplifica o refactoring.

Declare propriedades identificadoras em classes persistentes:

O Hibernate constrói propriedades identificadoras opcionais. Existem inúmeras razões para utilizá-las. Nós recomendamos que os identificadores sejam 'sintéticos', quer dizer, gerados sem significado para negócios.

Identifique chaves naturais:

Identifique chaves naturais para todas as entidades, e mapeie-as usando <natural-id>. Implemente equals() e hashCode() para comparar as propriedades que compõem a chave natural.

Coloque cada classe de mapeamento em seu próprio arquivo:

Não use um único código de mapeamento monolítico. Mapeie com.eg.Foo no arquivo com/eg/Foo.hbm.xml. Isto faz bastante sentido, especialmente em ambiente de equipe.

Carregue os mapeamentos como recursos:

Implemente os mapeamentos junto às classes que eles mapeiam.

Considere a possibilidade de externar as strings de consultas:

Esta é uma boa prática se suas consultas chamam funções SQL que não sejam ANSI. Externar as strings de consultas para mapear arquivos irá tornar a aplicação mais portável.

Use variáveis de vínculo.

Assim como em JDBC, sempre substitua valores não constantes por "?". Nunca use a manipulação de strings para concatenar valores não constantes em uma consulta. Até melhor, considere a possibilidade de usar parâmetros nomeados nas consultas.

Não gerencie suas conexões JDBC:

O Hibernate permite que a aplicação gerencie conexões JDBC, mas esta abordagem deve ser considerada um último recurso. Se você não pode usar os provedores de conexão embutidos, considere fazer sua implementação a partir de org.hibernate.connection.ConnectionProvider.

Considere a possibilidade de usar tipos customizados:

Suponha que você tenha um tipo Java, de alguma biblioteca, que precisa ser persistido mas não provê de acessórios necessários para mapeá-lo como um componente. Você deve implementar org.hibernate.UserType. Esta abordagem livra o código da aplicação de implementar transformações de/para o tipo Hibernate.

Use código manual JDBC nos afunilamentos:

Nas áreas de desempenho crítico do sistema, alguns tipos de operações podem se beneficiar do uso direto do JDBC. Mas por favor, espere até você saber se é um afunilamento. E não suponha que o uso direto do JDBC é necessariamente mais rápido. Se você precisar usar diretamente o JDBC, vale a pena abrir uma Session do Hibernate, embrulhar a sua operaçäo JDBC como um objeto org.hibernate.jdbc.Work e usar uma conexão JDBC. De modo que você possa ainda usar a mesma estratégia de transação e ocultar o provedor a conexão.

Entenda o esvaziamento da Session:

De tempos em tempos a sessão sincroniza seu estado persistente com o banco de dados. O desempenho será afetado se este processo ocorrer frequentemente. Você pode algumas vezes minimizar a liberação desnecessária desabilitando a liberação automática ou até mesmo mudando a ordem das consultas e outras operações em uma transação particular.

Em uma arquitetura de três camadas, considere o uso de objetos separados:

Ao usar a arquitetura do bean de sessão/servlet, você pode passar os objetos persistentes carregados no bean de sessão para e a partir da camada servlet/JSP. Use uma nova sessão para manipular cada solicitação. Use a Session.merge() ou a Session.saveOrUpdate() para sincronizar objetos com o banco de dados.

Em uma arquitetura de duas camadas, considere o uso de contextos de longa persistência:

As Transações do Banco de Dados precisam ser as mais curtas possíveis para uma melhor escalabilidade. No entanto, é geralmente necessário implementar transações de aplicações de longa duração, uma única unidade de trabalho a partir do ponto de vista de um usuário. Uma transação de aplicação pode transpor diversos ciclos de solicitação/resposta de cliente. É comum usar objetos desanexados para implementar as transações de aplicação. Uma outra alternativa, extremamente apropriada em uma arquitetura de duas camadas, é manter um único contato de persistência aberto (sessão) para todo o tempo de vida da transação de aplicação e simplesmente disconectá-lo do JDBC ao final de cada solicitação e reconectá-lo no início de uma solicitação subsequente. Nunca compartilhe uma sessão única com mais de uma transação de aplicação, ou você irá trabalhar com dados antigos.

Não trate as exceções como recuperáveis:

Isto é mais uma prática necessária do que uma "melhor" prática. Quando uma exceção ocorre, retorne à Transaction e feche a Sessão. Se não fizer isto, o Hibernate não poderá garantir que o estado em memória representará de forma precisa o estado persistente. Como este é um caso especial, não utilize a Session.load() para determinar se uma instância com dado identificador existe em um banco de dados, use Session.get() ou então uma consulta.

Prefira a busca lazy para associações:

Use a busca antecipada de forma moderada. Use as coleções proxy e lazy para a maioria das associações para classes que possam não ser completamente mantidas em cache de segundo nível. Para associações de classes em cache, onde existe uma enorme probabilidade de coincidir caches, desabilite explicitamente a busca antecipada usando lazy="false". Quando uma busca de união é apropriada para um caso específico, use a consulta com left join fetch.

Use o modelo sessão aberta na visualização, ou uma fase de construção para evitar problemas com dados não encontrados.

O Hibernate libera o desenvolvedor de escrever Objetos de Transferência de Dados (DTO). Em uma arquitetura tradicional EJB, os DTOs servem dois propósitos: primeiro, eles se deparam com o problema de que os beans de entidade não são serializáveis, depois, eles implicitamente definem uma fase de construção onde todos os dados a serem utilizados pelo view são buscados e conduzidos aos DTOs antes mesmo de retornar o controle à camada de apresentação. O Hibernate elimina o primeiro propósito. No entanto, você ainda precisará de uma fase de construção (pense em seus métodos de negócios como tendo um contrato estrito com a camada de apresentação sobre o quais dados estão disponíveis nos objetos desanexados) a não ser que você esteja preparado para manter o contexto de persistência (sessão) aberto no processo de renderização da visualização. Isto não é uma limitação do Hibernate. É uma solicitação fundamental para acesso a dados transacionais seguros.

Considere abstrair sua lógica comercial do Hibernate:

Oculte (Hibernate) o código de acesso a dados atrás de uma interface. Combine os modelos DAO e Sessão Local de Thread. Você pode também persistir algumas classes pelo JDBC handcoded, associado ao Hibernate via um UserType. Este é um conselho para aplicações "grandes o suficiente", não é apropriado para uma aplicação com cinco tabelas.

Não use mapeamentos de associação exóticos:

Casos de testes práticos para associações muitos-para-muitos reais são raros. A maioria do tempo você precisa de informação adicional armazenada na " tabela de link". Neste caso, é muito melhor usar associações dois um-para-muitos para uma classe de link intermediário. Na verdade, acreditamos que a maioria das associações é um-para-muitos e muitos-para-um, você deve tomar cuidado ao utilizar qualquer outro tipo de associação e perguntar a você mesmo se é realmente necessário.

Prefira associações bidirecionais:

As associações unidirecionais são mais difíceis para pesquisar. Em aplicações grandes, quase todas as associações devem navegar nas duas direções em consultas.