Análise de Desempenho dos Frameworks de Persistência Hibernate e EclipseLink Aurélio Vargas Ramos Júnior1, Edson A. Oliveira Junior2 Resumo. Nas aplicações de software é comum o armazenamento de dados persistentes. Esses sistemas são apoiados, em sua maioria, por gerenciadores de banco de dados relacionais, um framework de persistência gerencia a base de dados e o mapeamento entre a base de dados e os objetos. Este artigo compara a performance de dois frameworks de persistência – Hibernate e EclipseLink JPA usando uma base de dados de uma locadora de DVDs. Para facilitar tais testes, faz-se uso da API JPA que permite a fácil migração entre esses frameworks com pequenas alterações em sua configuração. Palavras-chave: framework, ORM, Hibernate, JPA, EclipseLink, benchmark. Abstract. In the applications software is common to store persistent data. These systems are supported mostly by managers relational database, a persistence framework manages the database and the mapping between the database and the objects. This paper compares the performance of two persistence frameworks – Hibernate and EclipseLink JPA using a DVD rental database. To facilitate these tests, it is using the JPA API that allows easy migration between these frameworks with small changes to your configuration. Keywords: framework, ORM, Hibernate, JPA, EclipseLink, benchmark. 1. Introdução Trabalhar com software orientado a objetos e bancos de dados relacionais pode ser trabalhoso e demorado, devido a incompatibilidade entre o paradigma de representação dos dados no modelo de objetos e o modelo de bancos de dados relacionais (conflito de impedância) [7]. Frameworks de mapeamento objeto relacional são uma solução. O Mapeamento Objeto-Relacional, (Object Relational Mapping - ORM) refere-se à técnica de mapeamento de dados a partir de uma representação do modelo de objeto em uma representação do modelo de dados relacional [3]. Servindo como uma ponte entre esse conflito de impedância o que torna a persistência de objetos mais simples, o trabalho do desenvolvedor é definir como os objetos são mapeados nas tabelas do banco e o Framework ORM faz o acesso ao banco, gerando inclusive os comandos em SQL necessários para tarefas padrões. Este artigo tem como meta comparar dois frameworks ORM, o Hibernate que é um dos mais consolidados por desenvolvedores Java e .NET e o EclipseLink, um framework extensível que permite interagir com vários serviços de dados, incluindo Banco de Dados, Web Services, Objetos XML, EIS, etc. Sendo assim, EclipseLink não implementa apenas o padrão JPA, mas também outros padrões como JAXB, JCA e SDO. Para tal comparação serão utilizadas algumas operações de 1 Aluno do curso de especialização em Desenvolvimento de Sistemas para Web – Universidade Estadual de Maringá (UEM) - Av. Colombo, 5790 – Bloco C56 – Maringá – PR – Brasil – [email protected] 2 Departamento de Informática – Universidade Estadual de Maringá (UEM) - Av. Colombo, 5790 – Bloco C56 – Maringá – PR – Brasil - [email protected] 1 persistência a saber: consultas simples e com joins, inserção, alteração e exclusão. Será utilizada uma média do desempenho dos procedimentos executados para encontrar o framework com menor tempo médio nas operações de persistência. Este artigo está organizado da seguinte forma: na Seção 2 são abordadas as tecnologias utilizadas para efetuar a comparação dos frameworks; na Seção 3 é realizado o estudo comparativo de desempenho entre Hibernate e EclipseLink e na Seção 4 é apresentada a conclusão e trabalhos que podem ser desenvolvidos futuramente. 2. Revisão Bibliográfica 2.1. Hibernate O framework Hibernate foi desenvolvido por uma equipe de programadores Java liderada por Gavin King e teve sua primeira versão divulgada em 2004. Segundo King [5], um dos objetivos ao criar o projeto era resolver seus problemas referentes à persistência causados pelo EJB 2.0, o qual considerava muito complexo. Devido à popularidade do projeto e por se tratar de um projeto “pessoal”, King utilizava seu tempo livre para que pudesse resolver problemas identificados pelos usuários do Hibernate. Com um escopo muito vasto, o projeto tornou-se inviável de ser mantido apenas nos tempos livres, assim King aceitou entrar para o JBoss Group, passando a ser remunerado para continuar a desenvolver o projeto, o que lhe permitiu dedicação completa ao Hibernate [5]. Com a especificação da JPA (Java Persistence API), solidificou-se como a implementação mais utilizada. Diversos projetos também 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 influências para a criação de uma nova especificação, a Bean Validation (JSR 303). A partir da versão 3.5, o Hibernate tornou-se uma implementação certificada para a JPA2 (JSR 317), lançada oficialmente no final de 2009. Várias annotations surgiram e muitos recursos foram aprimorados [9]. A escolha do Hibernate se deve ao fato de ele ser o framework ORM Java mais consolidado do mercado e implementar a especificação padrão Java EE para persistência, o JPA. 2.2. EclipseLink JPA O Eclipse Persistence Services Project, mais conhecido como EclipseLink, é uma solução abrangente de persistência open source. Seu projeto foi iniciado por uma doação do código-fonte completo e suítes de teste de produtos da Oracle TopLink. Esse projeto traz a experiência de mais de 12 anos de uso comercial e de Desenvolvimento [1]. Podese dizer que o EclipseLink evoluiu ao ponto de ser uma ferramenta superior ao TopLink. É dito que as próximas versões do TopLink incluirão o EclipseLink, assim como a próxima versão do Oracle Application Server [4]. Similar ao Hibernate, a intenção do projeto é oferecer uma solução baseada em padrões centrados no JPA [1]. A escolha do EclipseLink se deve porque apesar do Hibernate ter originado a JPA, o EclipseLink substituiu o produto “Oracle TopLink Essentials” e também se tornou a implementação de referência da versão JPA 2.0, sendo distribuído juntamente com o servidor de aplicações GlassFish V3 [10]. 2.3. Java Persistence API (JPA) O Java Persistence API (JPA) é uma especificação de persistência padrão aprovada pela JCP (Java Community Process) em meados de 2006, como parte da especificação EJB3 (Enterprise Java Beans 3). O JPA lida com a forma como os dados 2 relacionais são mapeados para objetos Java, a maneira que esses objetos são armazenados em um banco de dados relacional para que possam ser acessados posteriormente e, a existência continuada de um estado da entidade mesmo após a aplicação que usa termina. Além de simplificar o modelo de persistência da entidade, o JPA padroniza mapeamento objeto-relacional [4]. Neste artigo a base de dados foi mapeada utilizando do padrão JPA 2.0, para padronizar a aplicação o que torna possível que a aplicação seja independente do framework abordado. Sendo assim para cada teste, foi necessário somente alterar a biblioteca utilizada pela aplicação (framework). 2.4. Protótipo de aplicação para os casos de teste O objetivo deste trabalho é analisar o desempenho dos frameworks Hibernate e EclipseLink de ORM para a linguagem Java, para isso foram realizados testes utilizandose um protótipo de sistema simples para a gestão de locadora de filmes. A base de dados DVD rental é uma base de testes que foi portada para o Postgres do banco de dados Sakila, originalmente para MySQL e desenvolvida por Mike Hillyer do MySQL AB documentation team. Essa base foi modificada para se adequar às funcionalidades do PostgreSQL3. O DVD rental representa um processo de comércio de uma loja de locação de DVD com aproximadamente 300.000 registros. Possuindo muitos objetos como: 15 tabelas 1 trigger 7 views 8 funções 1 domínio 13 seqüências A Figura 1 ilustra o diagrama de entidade-relacionamento dessa base. 3 O esquema e seus dados estão disponíveis no endereço: http://www.postgresqltutorial.com/postgresqlsample-database/ 3 Figura 1: Modelo Entidade-Relacionamento do banco de dados Dvd Rental. 3. Estudo Comparativo de Desempenho entre Hibernate e EclipseLink JPA 3.1. Ambiente de Execuções Para efetuar as execuções de benchmark foi utilizado: Eclipse Kepler Java EE for Web Developers como ambiente de desenvolvimento integrado (IDE); Hibernate 4.3.1; EclipseLink JPA 2.5.1; Postgres 9.3; Java JDK 1.7.0_45; Sistema Operacional Linux Mint 16 Petra x86_64 GNU/Linux; e Sistema de arquivos - ext4. O computador usado para os testes é um Dell Intel optiplex 780 processador Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz, 4GB de memória RAM. O projeto pode ser baixado https://github.com/kawekaweau/jpa-bench-test. no repositório GitHub 3.2. Planejamento, Execução e Análise dos Resultados 4 3.2.1 Definição de Contexto e Planejamento do Estudo Comparativo 3.2.1.1 Objetivo do Estudo Comparar frameworks de persistência objeto-relacional, com o objetivo de identificar o melhor desempenho com relação à operações de persistência de dados em um banco de dados relacional, do ponto de vista de analistas e desenvolvedores de software, no contexto de um estudo de caso específico para operações de persistência relacionais. 3.2.1.2 Seleção das Variáveis Variáveis independentes (entrada/causa): o Framework de persistência - Hibernate e EclipseLink JPA; o Sistema Operacional Linux Mint 16 Petra x86_64 GNU/Linux; o Sistema de arquivos - ext4; e o Banco de Dados – Postgres 9.3.2. Variável dependente (observação/efeito): o Desempenho. 3.2.1.3 Definição das Hipóteses Hipótese Nula (H0): os tempos médios para a execução das operações de persistência usando Hibernate e EclipseLink JPA são os mesmos. Hipótese Alternativa (H1): o tempo médio de execução das operações de persistência usando Hibernate é menor que o tempo médio usando EclipseLink; e Hipótese Alternativa (H2): o tempo médio de execução das operações de persistência usando Hibernate é maior que o tempo médio usando EclipseLink. 3.2.2 Definição do plano de Testes 3.2.2.1 Procedimentos metodológicos Foram gravados tempos de relógio do sistema em dois momentos: na requisição e na obtenção da resposta. Calcula-se a diferença entre o tempo do momento de obtenção da resposta e o tempo do momento da requisição [6]. RES = T2 – T1 T1: Tempo obtido no momento da requisição. T2: Tempo obtido no momento da resposta. RES: Tempo de resposta. 3.2.2.2 Medidas 5 Boral e Dewitt [6] definem que quatro tipos de consultas são necessárias para a realização da análise de desempenho em sistemas de bancos de dados. Grupos Utilização de CPU Utilização de Disco Tipo 1 Baixo Baixo Tipo 2 Baixo Alto Tipo 3 Alto Baixo Tipo 4 Alto Alto Quadro 1: Tipos de consultas para análise de desempenho. Segundo os autores as consultas em bancos de dados consomem basicamente dois recursos de sistema: a) Ciclos de CPU: são consumidos tanto pelo sistema que executa a consulta (a aplicação) como por outras funções executadas pelo próprio SGBD. Ciclos de CPU também são consumidos pelo Sistema Operacional na iniciação das operações de disco. b) Operações de Disco: são consumidos durante a recuperação dos dados requeridos para responder uma consulta, armazenar dados de uma consulta no disco ou atividades de swapping. As consultas foram baseadas no Quadro 1, e nas métricas definidas para avaliação das alternativas de persistência de dados num ambiente objeto relacional, por Santos e Martins [7]. Foram utilizadas 2 métricas de consulta e 3 métricas de inserção de entidades. Sendo as consultas executadas as seguintes: Inserções Inserção simples; Inserção em Cascata; Inserção relacionamento ManyToMany; Consultas Consulta em profundidade; Consulta relacionamento M:N; Consulta de 1 tupla campo indexada; Consulta de 100 tuplas em 10000 não indexadas; Consulta 1.000 tuplas de 10.000 utilizando índice com relação a outra tabela; Consulta 100 tuplas de 10.000 utilizando de função agregada; 3.2.2 Execução do Estudo Comparativo O estudo comparativo foi conduzido com base na execução de 12 operações de persistência, sendo 6 consultas, 3 inserções e 3 exclusões. Cada consulta foi executada 100 vezes, sendo efetuado o cálculo médio do desempenho de cada consulta para ser criado o gráfico dos resultados. Inserções: para testar o tempo necessário para efetuar as inserções foram testados três tipos de inserções sendo: a inserção de uma entidade disjunta [2], na qual 6 foi inserida a entidade Actor. A inserção em um relacionamento M*N (relacionamento Actor Film) e uma inserção em cascata (foram persistidas as entidades City e Country através da persistência da entidade Address). Como mostra a Figura 2, o Hibernate levou um tempo maior que o EclipseLink na inserção em um relacionamento M*N, sendo que nas demais o Hibernate apresentou um desempenho melhor. 0,004 EclipseLink JPA 0,01 0,004 Hibernate 0,003 0 0,002 0,019 0,007 0,004 0,006 0,008 0,01 0,012 0,014 0,016 0,018 0,02 Tempo em segundos Simples Aninhada Relacionamento M*N Figura 2: Desempenho inserções. Consultas: foram efetuadas 6 tipos de consulta as duas primeiras são busca em profundidade (a partir da Entidade Payment obteve se a entidade Store através da junção com mais 3 entidades), nessa consulta o EclipseLink teve um melhor desempenho. A segunda consulta é o retorno de um relacionamento M*N, na qual foi buscada a entidade Rental de um cliente. Nessa consulta o Hibernate apresentou um melhor desempenho como mostra a Figura 3. 0,004 0,017 EclipseLink JPA 0,002 Hibernate 0 1,414 0,2 0,4 0,6 0,8 1 1,2 1,4 1,6 Tempo em segundos Busca Profundidade Relacionamento M*N Figura 3: Busca em Profundidade e consulta de um relacionamento M*N. Grupo 1: é uma consulta simples que busca 1 registro do tipo Customer por ID. Conforme o Quadro 1 apresentado na seção 3.2.2.2, essa consulta ocupa pouco processamento e utilização de disco. O comando utilizado para essa consulta foi: “SELECT c FROM Customer c WHERE c.customerId = 3”. Como mostra a Figura 4, o Hibernate efetuou a consulta em 0,007s e o EclipseLink JPA efetuou a consulta em 0,006s. 7 EclipseLink JPA 0,006 Hibernate 0,007 0,0054 0,0056 0,0058 0,006 0,0062 0,0064 0,0066 0,0068 0,007 0,0072 Tempo em segundos Figura 4: Seleção de um registro por atributo índice. Grupo 2: é uma consulta que busca 100 registros do tipo Film por titulo e ID utilizando o operador ‘>’. Conforme o Quadro 1 apresentado na seção 3.2.2.2, essa consulta ocupa pouco processamento e muito do disco. O comando utilizado para esta consulta foi: “FROM Film f WHERE f.title LIKE 'on%' AND f.filmId > 500”. Como mostra a Figura 5, o Hibernate efetuou a consulta em 0,004s e o EclipseLink efetuou a consulta em 0,005s. EclipseLink JPA 0,005 Hibernate 0,004 0 0,001 0,002 0,003 0,004 0,005 0,006 Figura 5: Seleção de 100 registros em 1000 utilizando operador LIKE. Grupo 3: é uma consulta que busca 1000 registros do tipo Payment através de uma junção com a entidade Rental e utilizando o ID de Rental para a seleção. Conforme o Quadro 1 apresentado na seção 3.2.2.2, essa consulta ocupa bastante processamento e pouca utilização do disco. O comando utilizado para essa consulta foi: “SELECT p FROM Payment p LEFT JOIN FETCH p.rental LEFT JOIN FETCH p.rental WHERE p.rental.rentalId = 2”. Como mostra a Figura 6, o Hibernate efetuou a consulta em 0,006s e o EclipseLink efetuou a consulta em 0,008s. EclipseLink JPA 0,008 Hibernate 0,006 0 0,001 0,002 0,003 0,004 0,005 0,006 0,007 0,008 0,009 Figura 6: Seleção de 1.000 registros de 100.000 utilizando índice de outra entidade. 8 Grupo 4: é uma consulta que busca 100 registros do tipo Payment por ID utilizando a função de agregação COUNT(). Conforme a tabela apresentada na seção 3.2.2.2, esta consulta ocupa bastante processamento e disco. O comando utilizado para esta consulta foi: “SELECT COUNT(p) FROM Payment p WHERE p.customer.customerId = 1 AND p.paymentId <= 100”. Como mostra a Figura 7, o Hibernate efetuou a consulta em 0,004s e o EclipseLink efetuou a consulta em 0,003s. EclipseLink JPA 0,003 Hibernate 0,004 0 0,0005 0,001 0,0015 0,002 0,0025 0,003 0,0035 0,004 0,0045 Figura 7: Selecionar 100 registros de 10.000 com função agregada. 3.2.3 Análise dos Dados do Estudo Comparativo Com base na execução das operações de persistência realizadas neste estudo o Hibernate obteve melhor desempenho em 5 operações. O EclipseLink JPA obteve melhor desempenho em 4 operações. Sendo assim, o framework Hibernate obteve o melhor desempenho total com base nas operações utilizadas neste estudo. O Quadro 2 mostra a quantidade de vezes que o framework foi superior categorizados por tipo de operação. Cláusulas Hibernate EclipseLink JPA INSERT 2 1 SELECT 3 3 Total 5 4 Quadro 2: Desempenho dos frameworks categorizados por tipo de operação. Assim, o estudo realizado fornece indícios de que a hipótese nula (H0) deve ser rejeitada e, conseqüentemente, a hipótese alternativa (H1) deve ser aceita, sendo que no total de operações, o framework Hibernate obteve melhor desempenho do que o framework EclipseLink JPA para as operações de consulta realizadas neste estudo. Já o framework EclipseLink obteve melhor desempenho médio nas operações. 4. Conclusões e Trabalhos Futuros Este artigo apresentou uma análise de desempenho baseada em benchmark por meio de uma série de operações de persistência com o intuito de fornecer evidências iniciais, para guiar na escolha do framework de persistência mais adequado para projetos de persistência baseados em mono-usuário e acesso não concorrente. Os resultados 9 obtidos devem ser associados à Base de Dados Postgres e Sistema Operacional Linux (Ext4). A utilização de outras bases de dados e sistema operacionais (ou sistema de arquivos), pode levar a resultados diferentes dos apresentados aqui. Com base nos resultados obtidos pode-se observar uma ligeira vantagem na utilização do Hibernate com relação ao EclipseLink para o conjunto de operações de consultas e, um desempenho aproximado porém com ligeira vantagem para o EclipseLink em operações de inserção definidas pelo benchmark utilizado. Com relação a trabalhos que podem ser desenvolvidos futuramente tem-se: (i) a análise de desempenho dos frameworks trabalhado no projeto, em um sistema multiusuário; (ii) planejamento e realização de uma análise do mesmo mapeamento em base de dados distintas, a base utilizada possui implementações para outros banco de dados; (iii) planejamento e realização de uma análise comparativa com sistemas de arquivos diferentes e (iv) estudo comparativo através de métricas qualitativas dos frameworks ORM. Referências Bibliográficas [1] CLARKE, D. Apresentando EclipseLink. Eclipse Zone, 30 jun 2008. Disponível em: <http://eclipse.dzone.com/articles/introducing-eclipselink?page=0,0>. Acesso em: 15, jan, 2014 [2] DIOGO V. DOS SANTOS, MARCELO DE R. MARTINS – Métricas para avaliação das alternativas de persistência de dados num ambiente objeto relacional. São Paulo: IME/USP, 2007. [3] HIBERNATE. Community Documentation. Hibernate Developer Guide. Disponível em: <http://docs.jboss.org/hibernate/core/4.3/devguide/en-US/html_single >. Acesso em: 15, jan, 2014. [4] HIGOR, M. Introdução ao EclipseLink. DevMedia. Disponível em: < http://www.devmedia.com.br/introducao-ao-eclipselink/29131#ixzz2rwAhkQqH >. Acesso em: 20, jan, 2014 [5] IZALMO PRIMO D S. Artigo Java Magazine 73 - Desenvolvendo com Hibernate . Disponível em: < http://www.devmedia.com.br/artigo-java-magazine-73-desenvolvendo-comhibernate/14756#ixzz2reXxyHvD>. Acesso em: 15, jan, 2014. [6] JADER D. S. T. C. - Estudo comparativo entre os frameworks de Mapeamento ObjetoRelacional Hibernate e Toplink. Maringá, Paraná: EspWeb/UEM. 2011. [7] PIETER VAN ZYL, DERRICK G. KOURIE, ANDREW BOAKE – Comparing the Performance of Object Databases and ORM Tools. Disponível em: <http://odbms.org/download/027.01 Zyl Comparing the Performance of Object Databases and ORM Tools September 2006.PDF>. Acesso em: 10, set, 2013. [8] VITOR GOTARDO - Análise de Desempenho dos Frameworks de Persistência Hibernate e Spring Data. Maringá, Paraná: EspWeb/UEM. 2013. [9] HANELLI TAVANTE – As novidades do Hibernate 4. Disponível em: < http://blog.caelum.com.br/as-novidades-do-hibernate-4/>. [10] SILVIO PAGANINI – Persistência a toda prova. Java Magazine 81. Disponível em: < http://www.devmedia.com.br/jpa-2-0-persistencia-a-toda-prova-java-magazine-81/17437/>. [6] MIKAEL KOPTEFF – The Usage and Performance of Object Databases compared with ORM tools in a Java environment. Disponível em: <http://www.odbms.org/download/045.01 Kopteff The Usage and Performance of Object Databases Compared with ORM Tools in a Java Environment March 2008.PDF>. Acesso em: 10, set, 2013. [8] SHOAIB MAHMOOD BHATTI, ZAHID HUSSAIN ABRO, FARZANA RAUF ABRO – Performance Evaluation of Java Based Object Relational Mapping Tools. Disponível em: <http://publications.muet.edu.pk/research_papers/pdf/pdf755.pdf>. Acesso em: 16, nov, 2013. [9] MIKE AULT, DONALD K. BURLESON, CLAUDIA FERNANDEZ, KEVIN KLEIN, BERT SCALZO - Database Benchmarking: Practical Methods for Oracle & SQL Server. Rampant Techpress, PAP/CDR edition, p. 19, 2007. []Leia mais em: Maven, JSF 2, Spring e Hibernate - Revista Java Magazine 101 http://www.devmedia.com.br/maven-jsf-2-spring-e-hibernate-revista-java-magazine101/23800#ixzz2vQ4TsGsk 10