Você está na página 1de 6

As novidades do Hibernate 4

Postado em 07. fev, 2012 por Hanneli Tavante em Java Compartilhar22 Um dos mais badalados frameworks de ORM no mundo Java (e popular tambm no .NET), o Hibernate recentemente ganhou sua verso 4.0 Final, que chega para arrebentar de novidades. O framework surgiu em 2001, por iniciativa de Gavin King, e logo se tornou amplamente utilizado devido a uma grande diversidade de recursos para mapeamento objeto relacional. Com a especificao da JPA (Java Persistence API), solidificou-se como a implementao mais utilizada. Diversos projetos tambm passaram a ser desenvolvidos pela equipe do Hibernate a fim de aprimorar os recursos existentes no framework. Muitos deles, em vez de serem anexados ao projeto Core, tornaram-se plugins, tais como Hibernate Search, o Hibernate OGM e o Hibernate Validator. Este ltimo, inclusive, teve fortes influncias para a criao de uma nova especificao, a Bean Validation (JSR 303). A partir da verso 3.5, o Hibernate tornou-se uma implementao certificada para a JPA2 (JSR 317), lanada oficialmente no final de 2009. Vrias annotations surgiram e muitos recursos foram aprimorados. Em dezembro de 2011, a verso 4.0 Final veio tona, trazendo algumas importantes novidades que gostaramos de destacar:

Redesign da SessionFactory
Possivelmente essa uma das grandes mudanas no Hibernate 4. Estvamos habituados a obter uma SessionFactory da seguinte forma:
private static final SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

Entretanto, agora o mtodo buildSessionFactory() est listado como deprecated, bem como as classes de Configuration: org.hibernate.cfg.Configuration e AnnotationConfiguration. A nova forma de se obter uma SessionFactory atravs do ServiceRegistry, que explicaremos adiante, lanado para esta verso 4:
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder() .configure().buildServiceRegistry(); MetadataSources metadataSources = new MetadataSources(serviceRegistry); metadataSources.addResource("algum.hbm.xml") .addAnnotatedClass(SuaEntidade.class); Metadata metadata = metadataSources.buildMetadata(); SessionFactory sessionFactory = metadata.buildSessionFactory();

Para que possamos obter uma SessionFactory, precisamos de um ServiceRegistry, seguido de um MetadataSources (eventualmente podemos adicionar recursos, classes anotadas, entre outros, de forma similar ao Configuration); a partir deste obtemos um Metadata e ento finalmente conseguimos uma SessionFactory.

Para obter uma EntityManagerFactory nada muda, podemos usufruir da classe javax.persistence.Persistence.

ServiceRegistry
Uma nova forma foi implementada para que o Hibernate gerencie seus servios. Services so classes que fornecem ao Hibernate diversos tipos de funcionalidades, tais como ClassLoader, conexo com o banco (ConnectionProvider), descoberta de dialetos apropriados, entre outros. Voc deve estar se perguntando por que isso um ponto interessante. O fato chave que agora todos os servios possuem uma interface. Caso queira, voc pode mudar a forma com que o Hibernate realiza algumas funcionalidades de uma maneira muito simples, apenas fazendo com que suas classes implementem a interface de servio do Hibernate. uma forma de desacoplar seu cdigo interno e se tornar mais malevel.

Suporte a Multi-Tenancy
Para que no conhece o termo, a vai um pequeno resumo em um modelo multitenant, possvel compartilhar os mesmos recursos fsicos para clientes/empresas diferentes, mas ao mesmo tempo permite-se que fiquem logicamente isolados. A frase anterior pode parecer abstrata, ento imagine diversas aplicaes de e-commerce. Muitas delas possuem um core muito similar e diferem apenas em questes de layout e UI. Imagine ento que fosse criada uma base de cdigo igual para todas essas lgicas de e-commerce e apenas o design de cada loja diferente fosse mudado; cada uma delas teria seu prprio namespace e um endereo na web; contudo a base de cdigo seria a mesma. Esses websites de lojas de e-commerce seriam cada um, um tenant. Podemos implementar o Multi-Tenancy de algumas formas: Instncias de bancos separadas (cada tenant possui sua prrpia instncia de banco); Schema separados (os tenants compartilham o mesmo banco fsico, entretanto cada um deles possui um schema); e tambm podemos implementar o Multi-Tenancy atravs de Particionamento (usamos o mesmo banco fsico e o mesmo Schema), onde os tenants so particionados de acordo com algum discriminator value (uma chave que apareceria em toda as tabelas) e uma nica tabela guarda os dados de cada um deles. O Hibernate 4 d suporte a esta ltima opo de maneira fcil. Para este caso, tomemos como exemplo uma tabela no banco denominada Cliente:
CLIENTE ( ID BIGINT, NOME VARCHAR, ... TENANT_ID VARCHAR (ou uma chave estrangeira) )

Note que precisamos do campo TENANT_ID, pois ele define a qual tenant nos referimos. Em um exemplo real, esse ID vai dizer a qual loja pertence determinado produto, por exemplo. Essa abordagem via Particionamento ainda d suporte a cache de segundo nvel.

Mas ser que sempre precisaremos nos lembrar de criar um TENANT_ID em nossas tabelas? Como poderamos ter algo como:
CLIENTE ( ID BIGINT, NOME VARCHAR, ... )

sem termos um TENANT_ID? Poderamos ter schemas separados e criarmos uma SessionFactory para cada tenant. Entretanto, isso seria invivel se tivssemos muitos tenants, pois muitas SessionFactories podem ser extremamente custosas para a memria. Uma outra ideia seria utilizarmos uma abordagem conhecida como application-supplied connections, onde abrimos uma Session em cada SessionFactory atravs de uma Connection especfica que fornecemos. Podemos dizer ao Hibernate qual Connection utilizar em cada contexto. Lembra-se de quando explicamos o ServiceRegistry? Um dos Services, o ConnectionProvider. Separando os schemas evitamos a necessidade de um TENANT_ID em cada tabela, mas perdemos a possibilidade de usar o cache de segundo nvel de maneira fcil, alm de ser mais trabalhoso realizar relatrios e estatsticas com mais de um cliente. O Hibernate 4 fornece essas alternativas bsicas para o cenrio multi-tenant, de forma quase transparente.

Usando o Hibernate 4
Quer ver o Hibernate 4 em ao? A maneira mais fcil de coloc-lo em seu projeto atravs do Maven:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.0.1.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>4.0.1.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-annotations</artifactId> <version>3.5.6-Final</version> </dependency>

Se voc utiliza alguma outra ferramenta de build, aqui voc encontra todas as dependncias necessrias declaradas para Ivy, Gradle, SBT, entre outros. Voc tambm pode baixar os jars necessrios para us-los diretamente. Caso voc use o JBoss AS 7 (conhea mais sobre essa nova verso do servidor), a verso 7.1 (ainda em Beta) j vem com o Hibernate 4 Final. Se voc preferir o cloud, pode experimentar o Hibernate 4 no Openshift (aqui h um tutorial no blog da Caelum).

Gostou? H muito mais nos links abaixo: Webinar de Hibernate 4 link Hibernate 4 post oficial do in.relation.to Multi-Tenancy mais informaes (tutorial introdutrio) Multi-Tenancy e Hibernate 4 Perguntas e Respostas Tambm no deixe de visitar os vrios posts da Caelum sobre Hibernate, inclusive o conhecido 7 hbitos dos desenvolvedores Hibernate e JPA altamente eficazes. Esperamos voc no nosso curso de Hibernate e JPA!

Os 7 hbitos dos desenvolvedores Hibernate e JPA altamente eficazes


Postado em 28. jan, 2008 por Paulo Silveira em Java Compartilhar47 Essa ltima semana tive a oportunidade de palestrar no RioJUG sobre JPA e Hibernate, onde fui muito bem recebido pelo Guilherme Chapiewski e Magno Cavalcante. Isso ocorreu durante o treinamento de Arquitetura Java que demos para diversos desenvolvedores da Globo.com, e onde tive o prazer de conhecer alguns desenvolvedores e arquitetos, como Vitor Pellegrino, Anselmo Alves, Wesley Silva, Alexandre Gazola, Tiago Motta, entre outros. Tambm vi o Ettore Luglio e o Daniel Passos.

Infelizmente durante a palestra no tive tempo de mostrar muitos recursos avanados e boas prticas do Hibernate, ento vou usar este espao para tal.

Precisamos conhecer todo pontencial de qualquer ferramenta, framework ou biblioteca que vamos usar em um projeto. Uma ferramenta boa, sem o devido conhecimento, resulta em projetos atrasados, com problemas de performance e desculpas do tipo O problema o [Hibernate|Struts|JSP, insira sua tecnologia aqui...], que gera uma quantidade excessiva de [queries|objetos|scriptlets|...] durante [lazy loading|requisies|...]. Isso vale em especial para ferramentas mais antigas, como JSP e Struts 1. Hoje em dia ambas possuem recursos poderosos que auxiliam em muito o desenvolvimento, mas alguns desenvolvedores acabam no se aprofundando e desconhecem esses detalhes que podem ser vitais no uso de determinadas tecnologias. Com o Hibernate no diferente. muito comum as pessoas culparem o Hibernate pela queda do banco de dados, performance das queries, nmero de objetos em memria, LazyInitializationException, e outros inmeros problemas os quais em sua maioria poderiam ter sido evitados com a utilizao de alguns recursos, boas prticas e bons hbitos no uso desse framework. Sem mais demora, os 7 hbitos: Connection Pool Usar o pool de conexes embutido com o Hibernate um erro comum, e a prpria documentao diz que voc no deve usa-lo em produo! Pode acontecer at connections leak! A Caelum teve timas experincias com o C3P0, e muito fcil configur-lo como Provider para o Hibernate. Second Level Cache Todos j passamos por situaes em que precisamos criar caches para as linhas de banco de dados mais acessadas. Aqui temos diversos problemas: sincronismo, gasto de memria, memory leak, tamanho do cache, poltica de prioridade da fila (LFU, LRU, FIFO, etc), tempo de expirao e modos de invalidar o cache. Escrever um cache eficiente e seguro um grande trabalho, imagine ainda dar suporte a um cache distribudo e que possa se aproveitar do disco rgido para no gastar tanta memria? Esse o papel do second level cache. Voc pode us-lo com diversos providers, sendo o EhCache um dos mais conhecidos. Query Cache Um recurso fantstico do Hibernate. No caso de voc ter queries que so executadas inmeras vezes, voc pode pedir para o Hibernate fazer o cache do resultado desta query. O interessante que ele no vai armazenar todos os objetos resultantes, e sim apenas suas primary keys: no momento que ele precisar executar novamente aquela query, ele j tem todos os IDs resultantes, e atravs destes ele consulta o second level cache, sem fazer um nico hit ao banco de dados! Esse cache ser invalidado quando alguma das tabelas envolvidas nesta query for atualizada, ou um determinado tempo passar. Controle do Lazy Algumas pessoas costumam reclamar do lazy loading, dizendo que em alguns casos teria sido melhor ele carregar tudo em uma nica query. Voc sempre pode redefinir o comportamento desses relacionamentos quando fizer uma query, atravs de um eager fetch. Stateless Session Algumas vezes precisamos fazer um processamento em batch de objetos, ou mesmo inserir uma quantidade grande deles na base de dados. Em muitos casos uma bulk operation o suficiente, mas se quisermos manter a Orientao a

Objetos, devemos tomar cuidado com a grande quantidade de objetos que ficaro armazenados no first level cache. A StatelessSession resolve esse problema: simplesmente no h first level cache e nenhum objeto se comportar como managed, tendo praticamente o mesmo efeito que chamar entityManager.clear() a cada operao. Open Session in View Na arquitetura MVC, muitas vezes renderizamos em nossa view diversas entidades do nosso modelo, e essas podem ter sido carregas pelo Hibernate. Se essas entidades possuem relacionamentos lazy, precisamos que a sesso esteja aberta no momento da renderizao da View, caso contrrio teremos uma LazyInitializaionException ou algum cdigo macarrnico para carregar relacionamentos que nem sempre precisamos. Para isso devemos manter a session aberta atravs de um filtro, interceptador ou algum outro mecanismo. Isso resulta no pattern Open Session in View e tambm se aplica ao EntityManager. O mesmo efeito pode ser obtido atravs de inverso de controle e injeo de dependncias atravs da anotao @PersistenceContext, que tratada por containers EJB3 e tambm por muitos frameworks web, como o Spring. O EJB3 ainda possui o conceito de um contexto de persistncia extendido, quem interessante em casos de conversaes longas: o EntityManager usado ser o mesmo enquanto aquele stateful session bean no for removido. Evitando nmero de queries excessivas (n+1) Se uma NotaFiscal possui muitos Items, e essa coleo lazy, gastaremos duas queries para buscar a NotaFiscal e seus respectivos Itens. Mas se temos uma lista de NotaFiscal resultante de uma query, para cada NotaFiscal teremos uma nova query executada para todo getItems invocados. 1 query para listar NotaFiscal, N queries para pegar os relacionamentos: o problema das n+1 queries. Voc deve usar as configuraes de batch-size e fetch-size para pedir ao Hibernate carregar as entidades/relacionamentos em blocos em vez de um em um. Voc tambm pode utilizar o second level cache nesses relacionamentos, diminuindo consideravelmente o nmero de queries disparada. Essas so apenas alguns dos hbitos, poderamos ainda falar sobre o bom tratamento de excees, o cuidado ao fechar todos os recursos abertos pelo Hibernate, o uso de queries nativas, o mapeamento de queries nativas para entidades atravs do ResultTransformer, filtros de colees, dynamic insert e update, a criao do seu prprio tipo de persistncia, e muitos outros. Conhecer bem o captulo de performance do Hibernate fundamental alm de um bom comeo.