<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog do Alone &#187; Persistência</title>
	<atom:link href="http://www.nelsonalone.com.br/category/frameworks/persistencia-frameworks/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.nelsonalone.com.br</link>
	<description>A tecnologia de forma simplificada</description>
	<lastBuildDate>Wed, 08 Feb 2012 03:29:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Auditoria com Envers</title>
		<link>http://www.nelsonalone.com.br/2012/02/08/auditoria-com-envers/</link>
		<comments>http://www.nelsonalone.com.br/2012/02/08/auditoria-com-envers/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 03:29:35 +0000</pubDate>
		<dc:creator>nelsonsozinho</dc:creator>
				<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Persistência]]></category>
		<category><![CDATA[envers]]></category>
		<category><![CDATA[hibernate]]></category>

		<guid isPermaLink="false">http://www.nelsonalone.com.br/?p=637</guid>
		<description><![CDATA[Qual o desenvolvedor que nunca foi questionado sobre a possibilidade de obter relatórios de quem modificou uma determinada informação? Se nunca aconteceu isso com você então pode esperar, isso é certo, vai acontecer. Soluções de auditoria podem ser encontradas em todas as linguagens através de frameworks e tutoriais que solucionam um determinado contexto. Assegurar um<a href="http://www.nelsonalone.com.br/2012/02/08/auditoria-com-envers/"> <br /><br /> (More)…</a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Qual o desenvolvedor que nunca foi questionado sobre a possibilidade de obter relatórios de quem modificou uma determinada informação? Se nunca aconteceu isso com você então pode esperar, isso é certo, vai acontecer.</p>
<p style="text-align: justify;">Soluções de auditoria podem ser encontradas em todas as linguagens através de <em>frameworks</em> e tutoriais que solucionam um determinado contexto. Assegurar um modelo comum tem sua parcela de dificuldade mas, de modo geral, é possível adquirir muita vantagem nesse ponto.</p>
<p style="text-align: justify;"><a href="http://www.nelsonalone.com.br/content/wp-content/uploads/2012/02/como-e-uma-auditoria-ppqa-564x272.jpg"><img class="aligncenter size-full wp-image-639" title="como-e-uma-auditoria-ppqa-564x272" src="http://www.nelsonalone.com.br/content/wp-content/uploads/2012/02/como-e-uma-auditoria-ppqa-564x272.jpg" alt="" width="564" height="272" /></a></p>
<p>&nbsp;</p>
<p style="text-align: justify;">Um tempo atrás, me deparei com uma situação para auditar tudo o que acontece na camada de persistência, com o objetivo de gerenciar todo o conjunto de modificações de objeto que continham valores monetários. Os gerentes queriam saber a procedência de alteração de uma série de elementos que foram armazenados, inclusive quem os armazenou e qual foi a URL executada para remove-lo. Nesse caso, foi necessário desenvolver uma série de <em>listeners</em> para realizar a leitura de elementos contidos na sessão e armazena-los. Porém, quando se trata de aplicações corporativas, normalmente estão espalhadas em outros servidores, normalmente provendo serviços que outras aplicações acessam. O maior problema disso tudo é que armazenar o histórico de um objeto em uma outra base de dados, normalmente com o auxílio desses serviços (seja EJB, Web Services ou RESt) é um trabalho a mais, gerando um deley desnecessário para a aplicação. Em muitos casos, o armazenamento dos logs no <em>schema</em> utilizado pela aplicação minimizaria consideravelmente o fator tempo utilizado para o complemento da transação .</p>
<p style="text-align: justify;">No mundo Java, o <em>framewok</em> predominante é o <em>Hibernate</em>. É muito difícil projetar um aplicação que não utilize o framework para mapeamento objeto-relacional da linguagem Java. É um excelente framework, na minha opinião, o mais bem sucedido quando se trata de funcionalidades providas por frameworks. A auditoria realizada com esse <em>fremework</em> pode ser feita utilizando <em>listeners</em> e que executam call-backs dispondo de eventos que podem executar ações antes ou depois da persistência de objetos. Ainda assim, a dificuldade e o tempo de desenvolvimento de uma solução mais viável e rápida fica a desejar.  Dessa forma, para preencher a lacuna, utilizaríamos recursos de aspectos do Spring para uma coisa mais elaborada. Manter uma solução como essa, em certos pontos, despadronizada e mal documentada, se tornaria um caos. Normalmente tratativas reais no ambiente onde se desenvolve o software.</p>
<p style="text-align: justify;"><a href="http://www.nelsonalone.com.br/content/wp-content/uploads/2012/02/hibernate.png"><img class="aligncenter size-full wp-image-640" title="hibernate" src="http://www.nelsonalone.com.br/content/wp-content/uploads/2012/02/hibernate.png" alt="" width="250" height="240" /></a></p>
<p style="text-align: justify;">Hoje em dia, acompanhado desse <em>framework</em> está o <em>Envers</em>, que é um framework de auditoria nativo do <em>Hibernate</em>, tanto que ele vem <a title="Envers junt-se ao hibernate" href="http://www.infoq.com/br/news/2008/12/envers_joins_hibernate">junto com o pacote distribuído no site do produto</a>.</p>
<p style="text-align: justify;">Resolvi testar o <em>Envers</em> em uma aplicação piloto para conhecer as funcionalidades de auditoria provida por esse framework. Logo de primeira, fiquei impressionado com a facilidades de integração com o <em>Hibernate</em>. É só incluir a lib e utilizar as anotações. Só isso e nada mais. Porém, o framework tem suas particularidades. Para cada entidade que deseja auditar é necessário incluir uma anotação, seja ela no atributo em questão ou no todo da classe para anotar todos os atributos. Após rodar o projeto, no momento da atualização do <em>schema</em>, será criada a tabela de auditoria como o complemento do nome “AUD”.</p>
<p style="text-align: justify;"><img src="webkit-fake-url://84FDC214-6382-48BA-93F7-F06E72D03713/application.pdf" alt="" /></p>
<p style="text-align: justify;"> Em objeto de classe que for anotada com @<em>Audited</em>, será gerada uma estrutura semelhando ao desenho acima. As tabelas “AUD” armazenam os atributos da classe que foram anotadas.</p>
<p style="text-align: justify;">Nem sempre o que o <em>framework </em>oferece é o suficiente para executar por completo nossos requisitos de negócio. De acordo com a configuração default, foi oferecido ao desenvolvedor registrar as modificações dos objetos com revisões. Porém, em algumas situações, talvez necessitamos de um conjunto de informações mais rico. Ou melhor, precisamos registrar a data que o objeto foi modificado, por quem e qual o caminho que o usuário percorreu até concluir o conjunto de funcionalidades.</p>
<p style="text-align: justify;">Para isso, será necessário a inclusão de dois elemento para que possam trabalhar em conjunto. A anotação @<em>RevisionEntity</em> e o <em>listener</em> <em>RevisionListener</em>.</p>
<p style="text-align: justify;">A anotação permite escolher uma classe que representará uma entidade que irá conter os atributos a mais necessários para serem armazenados. O <em>listener</em> incluirá de escutar a modificação realizada no objeto e executar um método para executar alguma programação que, na maioria das vezes, seria uma extração de informação de algum objeto que está na sessão ou de um método de armazenamento temporário de objetos. Isso ficaria mais ou menos assim:</p>
<p style="text-align: justify;"><a href="http://www.nelsonalone.com.br/content/wp-content/uploads/2012/02/Captura-de-Tela-2012-02-07-às-23.00.15.png"><img class="aligncenter size-full wp-image-638" title="Captura de Tela 2012-02-07 às 23.00.15" src="http://www.nelsonalone.com.br/content/wp-content/uploads/2012/02/Captura-de-Tela-2012-02-07-às-23.00.15.png" alt="" width="962" height="330" /></a></p>
<p style="text-align: justify;">A cada modificação realizada o método <em>newRevision </em>é executado, podendo aí utilizar do mecanismo para preencher os campos da entidade auxiliar.</p>
<p style="text-align: justify;">Esses são apenas recursos que considero o mais básico possível que uma aplicação de médio porte pode ter. O <em>Envers</em> possui mais recursos para armazenamento, cujo conteúdo está disponível na documentação do produto.</p>
<p style="text-align: justify;">As consultas são um caso a parte. O <em>Envers</em> utiliza o conceito de revisão, uma ideia bem semelhante ao <em>Subversion</em>, fazendo com que cada modificação realizada no objeto gere uma nova revisão. A revisão é armazenada juntamente com os dados que foram modificados, inclusive o seu tipo de modificação que foi realizada.</p>
<p style="text-align: justify;">A ideia dos tipos de transação são bem claros quando olhamos o dados armazenados. No teste que eu fiz no MySQL podemos ver o campo REVTYPE. Onde é armazenado os tipos de modificações realizadas no objeto:</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nelsonalone.com.br/2012/02/08/auditoria-com-envers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hibernate/JPA – Utilizando SQL sem perder o vinculo dos objetos relacionados</title>
		<link>http://www.nelsonalone.com.br/2011/09/22/hibernatejpa-%e2%80%93-utilizando-sql-sem-perder-o-vinculo-dos-objetos-relacionados/</link>
		<comments>http://www.nelsonalone.com.br/2011/09/22/hibernatejpa-%e2%80%93-utilizando-sql-sem-perder-o-vinculo-dos-objetos-relacionados/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 16:51:37 +0000</pubDate>
		<dc:creator>nelsonsozinho</dc:creator>
				<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Persistência]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA]]></category>

		<guid isPermaLink="false">http://www.nelsonalone.com.br/?p=581</guid>
		<description><![CDATA[Não há dúvidas de que o hibernate é um excelente ORM, se não o melhor que há no mercado. Porém, muitas pessoas, satisfeitas com os procedimentos iniciais de aprendizado do framework, não se dão conta das demais funcionalidades disponíveis para o desenvolvedor. A lista é vasta, confesso que posso não conhecer a metade, mas alguns<a href="http://www.nelsonalone.com.br/2011/09/22/hibernatejpa-%e2%80%93-utilizando-sql-sem-perder-o-vinculo-dos-objetos-relacionados/"> <br /><br /> (More)…</a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Não há dúvidas de que o hibernate é um excelente ORM, se não o melhor que há no mercado. Porém, muitas pessoas, satisfeitas com os procedimentos iniciais de aprendizado do framework, não se dão conta das demais funcionalidades disponíveis para o desenvolvedor. A lista é vasta, confesso que posso não conhecer a metade, mas alguns dias atrás, uma dessas funcionalidades me ajudou muito.</p>
<p style="text-align: justify;">Um objeto persistente, para o hibernate, é uma entidade que contem relacionamentos com outras entidades que juntos formam uma relação. Em diversas situações, na maioria das vezes no mundo real, essa relação se torna complexa quando existe a necessidade de relação com outras entidades, somado com o numero enorme de dados relacionados. Existem várias formas de obter essas esses dados relacionados, uns que permitem obter todo o conjunto de dados relacionados ao carregar o objeto (eager), outro no momento que a relação é obtida (lazy). Outras alternativas podem ser utilizadas em conjunto, como, as consultas nomeadas atreladas ao carregamento do objeto. Porém, apenas obter a lista de desses informações não é suficiente para a aplicação, fazendo com que o desenvolvedor utiliza consultas mais elaboradas com HQL ou criteria.</p>
<p style="text-align: justify;">A forma como o framework monta as consultas é na maioria das vezes genérica e pouco intuitiva, fazendo com que o desenvolvedor opte por utilizar o SQL nativo, ou portar a consulta para uma Stored Procedure para construir uma consulta mais elaborada. É uma estratégia plausível quando a aplicação necessita de desempenho mas, isso tiraria a principal vantagem do framework; o acesso as relações que são representadas pelo relacionamento entre os objetos. Existe uma maneira muito simples de executar uma consulta SQL mantendo o relacionamento entre os objetos.</p>
<p style="text-align: justify;">Para o framework, os objetos persistentes são de extrema importância. Quando o framework é executado pela primeira vez, ele adiciona uma série de funcionalidade nos objetos persistentes que permite realizar as operações em suas relações. A maneira com que o framework realiza essa tarefa é pela <a title="Instrumentação de cógigo - Wikipedia" href="http://en.wikipedia.org/wiki/Instrumentation_%28computer_programming%29">Instrumentação</a> de código. A instrumentação nada mais de uma técnica de incluir alterações do código do programa mesmo após a sua compilação. O conceito pode ser semelhante com Reflexão e AOP, mas existem particularidades que tornam os conceitos bem distintos. Por ser um assunto muito pesquisado e com referencias em abundância, é um assunto para ser tratado outra hora. No hibernate, isso é feito através da lib ASM, que é um extenso conjunto de utilidade que permitem a plicar esse conceito nas classes escritas em linhagem Java.</p>
<p>Bom, para que o framework compreenda que o resultado de uma consulta SQL possa ser vinculado a um objeto é necessário que o retorno corresponda aos atributos do objeto, sendo que o objeto possa ser reconhcido pelo motor de consulta. Ex:<code></code></p>
<p><code><br />
List&lt;ClasseQualquer&gt; planos = new ArrayList&lt;ClasseQualquer&gt;();<br />
String queryStr = queryUtils.findValue(nome_da_query); //obtem a string de consulta<br />
Query query = entityManager.createNativeQuery(queryStr, ClasseQualquer.class);</code></p>
<p>&nbsp;</p>
<p>Obtendo um objeto Query configurado como acima, é possível realizar operações como essas abaixo:<code><br />
</code></p>
<p><code>List dados = instanciaObjetoQualquer.getDadosParticulares();</code></p>
<p>&nbsp;</p>
<p>Esse simples macete pode ajudar bastente para obter objetos, que necessitem manter o acesso aos objetos relacionados, através de consultas bem elaboradas e com o desempenho do SQL.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nelsonalone.com.br/2011/09/22/hibernatejpa-%e2%80%93-utilizando-sql-sem-perder-o-vinculo-dos-objetos-relacionados/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hibernate: Schema export através de tasks do ANT</title>
		<link>http://www.nelsonalone.com.br/2009/08/27/hibernate-schema-export-atraves-de-tasks-do-ant/</link>
		<comments>http://www.nelsonalone.com.br/2009/08/27/hibernate-schema-export-atraves-de-tasks-do-ant/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 04:33:19 +0000</pubDate>
		<dc:creator>nelsonsozinho</dc:creator>
				<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Persistência]]></category>
		<category><![CDATA[annotation]]></category>
		<category><![CDATA[ant]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[persistence]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.nelsonalone.com.br/?p=336</guid>
		<description><![CDATA[É inegável que o hibernate é um excelente framework de mapeamento objeto relacional. Seus recursos de mapeamento, persistência, transação simplificadas, suporte a queries SQL, HQL, criteria, entre outros, justificam a sua utilização em massa pela comunidade Java. Não foi por acaso sua utilização como modelo para a especificação JPA. Alem das funcionalidades do contexto de<a href="http://www.nelsonalone.com.br/2009/08/27/hibernate-schema-export-atraves-de-tasks-do-ant/"> <br /><br /> (More)…</a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">É inegável que o hibernate é um excelente framework de mapeamento objeto relacional. Seus recursos de mapeamento, persistência, transação simplificadas, suporte a queries SQL, HQL, criteria, entre outros, justificam a sua utilização em massa pela comunidade Java. Não foi por acaso sua utilização como modelo para a especificação JPA.</p>
<p style="text-align: justify;">Alem das funcionalidades do contexto de persistência também podemos contar com as funcionalidades extras que foram desenvolvidas pelo time de desenvolvimento, hoje pertencente a JBoss. Estou falando do pacote hibernate-tools.jar, contido no plugin feito para o eclipse, com o intuito de auxiliar no processo de configuração, mapeamento, importação de schemas e mecanismo de interpretação e execução de HQL. O link para download do plugin encontra-se <a href="http://downloads.sourceforge.net/jboss/HibernateTools-3.2.4.GA-R200905070146-H18.zip">aqui</a>.</p>
<p style="text-align: justify;">Tive a necessidade de fazer com que todo o schema fosse exportado para o banco de dados ao executar uma simples task do Ant. Funcionalidade que facilitaria muito a vida da equipe ao modificar o mapeamento das entidades do projeto, sendo apenas necessário executar a task para exportar as modificações para o SGBD. Para isso, desenvolvi uma task personalizada para solucionar esse problema. A task funcionava bem, mas chegou um ponto que não nos atendia. Portanto, vi que uma boa alternativa seria utilizar as tasks do hibernate-tools.</p>
<p style="text-align: justify;">O pacote hibernate-tools.jar contem um conjunto de tasks que permitem a execução de procedimentos básicos de persistência através de simples tasks do <a href="http://ant.apache.org/">Ant</a>. As tasks são variadas, portanto é possível utiliza-las para; exportar schemas, gerar os inserts do mapeamento em um arquivo .sql, gerar os hbm.xml (se não tiver utilizando anotações) entre outras coisas. Mais um detalhe: o pacote hibernate-tools.jar é completamente independente do plugin.</p>
<p style="text-align: justify;">A configuração para utilizar as tasks a princípio é simples, porém levei um tempo para acertar, já que meu projeto estava mal configurado e gastei muito tempo para descobrir o problema. Vou levar em conta que o seu projeto está devidamente configurado e fazendo todas as operações básicas (insert, update e delete) no banco de dados.</p>
<p style="text-align: justify;">Para uma simples exportação do schema para o banco de dados, a primeira coisa que você deve fazer é adicionar o pacote hibernate-tools.jar no classpath do projeto. Após isso é necessário incluir uma referencia a classe que representa a task. Nesse caso, assim como está abaixo:</p>
<p style="text-align: justify;">
<p style="text-align: justify;"><strong><code>&lt;taskdef name="hibernatetool" classname="org.hibernate.tool.ant.HibernateToolTask" classpathref="path.lib" /&gt;</code></strong></p>
<p style="text-align: justify;"><strong><br />
</strong></p>
<p style="text-align: justify;">Após isso, é necessário incluir um target que fará todo o trabalho sujo. Nessa target deve conter, dentro do <code>&lt;hibernatetool&gt;</code>, no mínimo as tasks <code>&lt;annotationconfiguration/&gt;</code> e <code>&lt;hbm2ddl/&gt;</code> para fazer o processo de configuração e a exportação de todas as configurações de mapeamento incluídas nas classes. Vamos ver o detalhe abaixo:</p>
<p style="text-align: justify;"><code><br />
<strong> &lt;target name="generate" depends="compile"&gt;<br />
&lt;hibernatetool destdir="${dir.build}/generated"&gt;<br />
&lt;classpath&gt;<br />
&lt;path location="${dir.out.classes}"&gt;&lt;/path&gt;<br />
&lt;/classpath&gt;<br />
&lt;annotationconfiguration propertyfile="${dir.out.classes}/hibernate.properties"  configurationfile="${dir.out.classes}/hibernate.cfg.xml" /&gt;<br />
&lt;hbm2ddl drop="true" create="true" export="true" outputfilename="../schema.sql" delimiter=";" format="true" /&gt;<br />
&lt;hbm2dao /&gt;<br />
&lt;/hibernatetool&gt;<br />
&lt;/target&gt;</strong></code></p>
<p style="text-align: justify;">
<p style="text-align: justify;">Reparem que é necessário ter os .class incluídos no <code>&lt;classpath/&gt;</code> como descrito acima, pois é daí que vem todo o mapeamento dos objetos. A propriedade <code>&lt;annotationconfiguration/&gt;</code> representa as configurações do seu SGBD (hibernate.properties) e das classes persistentes (hibernate.cfg.xml). Claro que o arquivo cfg.xml pode conter as configurações do SGBD mas eu achei melhor separá-los.</p>
<p style="text-align: justify;">A task <code>&lt;hbm2dll/&gt;</code> é o elemento principal do processo de exportação do schema. Nela é possível definir se, ao exportar o schema, irá dropar as tabelas existentes e criar uma nova estrutura e além do mais irá criar um arquivo .sql contendo tudo o que foi feito no banco.</p>
<p style="text-align: justify;">Adicionei a task <code>&lt;hbm2dao/&gt;</code> apenas para mostrar o DAO gerado conforme as entidades geradas. Acredito que isso seja útil para os projetos que não utilizam o suporte aos DAOs do Hibernate do Spring.</p>
<p style="text-align: justify;">Bom pessoal, esse foi um processo que me atendeu perfeitamente nos projetos que desenvolvo, portanto, segue a dica para os leitores. Chega de ficar mexendo nas propriedades <code>hibernate.hbm2ddl.auto create-drop</code> e escrever tarks personalizadas para essa tarefa.</p>
<p style="text-align: justify;">
<p style="text-align: justify;">[]s</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nelsonalone.com.br/2009/08/27/hibernate-schema-export-atraves-de-tasks-do-ant/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

