Ol\u00e1 amigos, muitos vezes precisamos gerenciar a transa\u00e7\u00e3o JPA em nosso servidor e n\u00e3o temos a op\u00e7\u00e3o de utilizar EJB ou Spring. Dessa forma, ficar a cargo do programador gerenciar o in\u00edcio e fim da transa\u00e7\u00e3o jpa como o banco dados. Entre a v\u00e1rias alternativas<\/p>\n
Ent\u00e3o vamos mostrar uma das formas de se fazer isso.
\n <\/p>\n
\n
Essa abordagem \u00e9 muito comum e utilizada quando nossa aplica\u00e7\u00e3o fica dispon\u00edvel no Apache Tomcat<\/a>. Ele \u00e9 um servidor WEB e n\u00e3o <\/strong>possui suporte a tecnologia EJB, por exemplo. Veja que o c\u00f3digo acima precisamos fazer a chamada aos m\u00e9todos “session.beginTransaction();” e “session.getTransaction().commit();” isto \u00e9 necess\u00e1rio, pois estamos utilizando o padr\u00e3o BTM (Bean-Managed Transactions), ou seja, nossa aplica\u00e7\u00e3o tem que iniciar, executar a opera\u00e7\u00e3o desejada e em seguida concluir a opera\u00e7\u00e3o com um “commit” e caso ocorra um erro precisamos enviar o comando “session.getTransaction().rollback();” para desfazer as opera\u00e7\u00e3o que foram executadas.<\/p>\n Para o post de hoje utilizaremos o Exemplo completo com JSF Primefaces + Hibernate + MySQL<\/a> criado aqui no Blog para auxiliar no nosso aprendizado.<\/p>\n Fa\u00e7a download o WAR e importe no seu eclipse. Para lembrar como isso funciona acesse Importando um projeto Web no Eclipse<\/a> Ent\u00e3o criaremos um filtro, para isso ap\u00f3s a importa\u00e7\u00e3o no eclipse selecione o projeto com o bot\u00e3o direito “New ==> Filter” no campo pacote adicione: O c\u00f3digo do seu filtro ficar\u00e1 dessa maneira:<\/p>\n Nesse filtro estamos fazendo o controle de transa\u00e7\u00e3o jpa de todas as opera\u00e7\u00f5es no nosso banco de dados. Antes de fazer qualquer a\u00e7\u00e3o no banco de dados as chamadas da nossa aplica\u00e7\u00e3o passam no nosso filtro que cria uma sess\u00e3o e inicia uma transa\u00e7\u00e3o jpa “beginTransaction”. Em seguida \u00e9 executado o m\u00e9todo “chain.doFilter(request, response);” que permite a execu\u00e7\u00e3o do m\u00e9todo desejado no DAO. Em seguida a execu\u00e7\u00e3o volta para o nosso FiltroJPA que conclui a transa\u00e7\u00e3o jpa executando um commit.<\/p>\n Agora vamos analisar a nossa classe “AlunoHibernateDAO” que ficou simplificada em rela\u00e7\u00e3o \u00e0 vers\u00e3o que est\u00e1 no Post Exemplo completo com JSF Primefaces + Hibernate + MySQL<\/a>.<\/p>\n Vejamos como foram as mudan\u00e7as, para isso compare o m\u00e9todo incluir <\/p>\n Antes:<\/p>\n E depois!<\/p>\n Isto n\u00e3o \u00e9 MAGIA e sim TECNOLOGIA!<\/strong> Tamb\u00e9m fizemos a altera\u00e7\u00e3o da Classe Hibernate Util para pegar sempre a mesma sess\u00e3o:<\/p>\n No m\u00e9todo “getSession()” tivemos que mudar de openSession para “getCurrentSession()” isso faz com que nossa aplica\u00e7\u00e3o reutilize a sess\u00e3o que est\u00e1 aberta. Adicionamos a linha: “ Esta forma de controle de transa\u00e7\u00e3o jpa \u00e9 muito interessante quando n\u00e3o podemos utilizar o CTM – Container Transaction Manager. Isso \u00e9 comum em aplica\u00e7\u00f5es que s\u00f3 rodam em container Web, sistemas legados ou aplica\u00e7\u00f5es que tem como premissa o uso de tecnologias Servlet ou JSF. Para pegar o c\u00f3digo completo clique aqui<\/a><\/p>\n Veja como ficar\u00e1 a nossa aplica\u00e7\u00e3o: Ent\u00e3o amigos por hoje \u00e9 s\u00f3 e vida que segue.<\/strong><\/em><\/p>\n
\n Em aplica\u00e7\u00f5es desktop(JSE), quando utilizamos JPA precisamos controlar a transa\u00e7\u00e3o jpa manualmente. Veja o exemplo abaixo dispon\u00edvel em nosso tutorial sobre JPA com Hibernate<\/a>.<\/p>\n\r\npublic void incluir(Aluno aluno) {\r\n\t\ttry {\r\n\t\t\tsession = HibernateUtil.getSession();\r\n\t\t\tsession.beginTransaction();\r\n\t\t\tsession.save(aluno);\r\n\t\t\tsession.getTransaction().commit();\r\n\t\t} catch (Exception e) {\r\n\t\t\tsession.getTransaction().rollback();\r\n\t\t\te.printStackTrace();\r\n\t\t} finally {\r\n\t\t\tsession.close();\r\n\t\t}\r\n\t}\r\n<\/pre>\n
\n“br.com.feltex.academicnet.filter” e no campo Class Name digite: “FiltroJPA”. Selecione Finish.<\/p>\n\r\npackage br.com.feltex.academicnet.filter;\r\n\r\nimport java.io.IOException;\r\n\r\nimport javax.servlet.Filter;\r\nimport javax.servlet.FilterChain;\r\nimport javax.servlet.FilterConfig;\r\nimport javax.servlet.ServletException;\r\nimport javax.servlet.ServletRequest;\r\nimport javax.servlet.ServletResponse;\r\nimport javax.servlet.annotation.WebFilter;\r\n\r\nimport org.hibernate.Session;\r\n\r\nimport br.com.feltex.hibernate.util.HibernateUtil;\r\n\r\n\/\/ Aten\u00e7\u00e3o que apenas as chamadas JSF ser\u00e3o filtradas por este filtro\r\n@WebFilter(\"*.xhtml\")\r\npublic class FiltroJPA implements Filter {\r\n\r\n\tpublic FiltroJPA() {}\r\n\r\n\tpublic void destroy() {}\r\n\r\n\tpublic void doFilter(ServletRequest request, ServletResponse response,\r\n\t\t\tFilterChain chain) throws IOException, ServletException {\r\n\t\tSession session = HibernateUtil.getSession();\r\n\t\ttry {\r\n\t\t\tsession.beginTransaction();\r\n\t\t\tchain.doFilter(request, response);\r\n\t\t\tsession.getTransaction().commit();\r\n\t\t} catch (Exception e) {\r\n\t\t\tsession.getTransaction().rollback();\r\n\t\t\te.printStackTrace();\r\n\t\t} finally {\r\n\t\t\tif (session != null && session.isOpen()) {\r\n\t\t\t\tsession.close();\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tpublic void init(FilterConfig fConfig) throws ServletException {}\r\n} \r\n<\/pre>\n
\r\npackage br.com.feltex.academicnet.dao.hibernate;\r\n\r\nimport java.util.List;\r\n\r\nimport org.hibernate.Criteria;\r\nimport org.hibernate.Session;\r\nimport org.hibernate.criterion.Order;\r\nimport org.hibernate.criterion.Restrictions;\r\n\r\nimport br.com.feltex.academicnet.dao.AlunoDAO;\r\nimport br.com.feltex.academicnet.entidade.Aluno;\r\nimport br.com.feltex.hibernate.util.HibernateUtil;\r\n\r\npublic class AlunoHibernateDAO implements AlunoDAO {\r\n\r\n\tprivate Session session;\r\n\r\n\tpublic void alterar(Aluno p) {\r\n\t\tsession = HibernateUtil.getSession();\r\n\t\tsession.merge(p);\r\n\t}\r\n\r\n\tpublic Aluno consultar(Aluno aluno) {\r\n\t\tsession = HibernateUtil.getSession();\r\n\t\treturn (Aluno) session.get(Aluno.class, aluno.getMatricula());\r\n\t}\r\n\r\n\tpublic void excluir(Aluno p) {\r\n\t\tsession = HibernateUtil.getSession();\r\n\t\tAluno alunoPesquisado = consultar(p);\r\n\t\tsession.delete(alunoPesquisado);\r\n\t}\r\n\r\n\tpublic boolean existe(Aluno aluno) {\r\n\t\tAluno a = consultar(aluno);\r\n\t\treturn (a.getMatricula() != null);\r\n\t}\r\n\r\n\tpublic void inserir(Aluno p) {\r\n\t\tsession = HibernateUtil.getSession();\r\n\t\tsession.save(p);\r\n\t}\r\n\r\n\t@SuppressWarnings(\"unchecked\")\r\n\tpublic List
\r\npublic void incluir(Aluno aluno) {\r\n\t\ttry {\r\n\t\t\tsession = HibernateUtil.getSession();\r\n\t\t\tsession.beginTransaction();\r\n\t\t\tsession.save(aluno);\r\n\t\t\tsession.getTransaction().commit();\r\n\t\t} catch (Exception e) {\r\n\t\t\tsession.getTransaction().rollback();\r\n\t\t\te.printStackTrace();\r\n\t\t} finally {\r\n\t\t\tsession.close();\r\n\t\t}\r\n\t}\r\n<\/pre>\n
\r\npublic void inserir(Aluno p) {\r\n\t\tsession = HibernateUtil.getSession();\r\n\t\tsession.save(p);\r\n\t}\r\n<\/pre>\n
\n O que fizemos neste caso foi a passagem do controle de transa\u00e7\u00e3o jpa para o filtro que ir\u00e1 interceptar todas as chamadas (xhtml) antes de ocorrerem as opera\u00e7\u00f5es no DAO.<\/p>\n\r\n\r\npackage br.com.feltex.hibernate.util;\r\n\r\nimport org.hibernate.Session;\r\nimport org.hibernate.SessionFactory;\r\nimport org.hibernate.cfg.Configuration;\r\nimport org.hibernate.service.ServiceRegistry;\r\nimport org.hibernate.service.ServiceRegistryBuilder;\r\nimport org.hibernate.tool.hbm2ddl.SchemaExport;\r\n\r\npublic class HibernateUtil {\r\n\r\n\tpublic static void main(String[] args) {\r\n\t\tSystem.out.println(\"Inicio\");\r\n\r\n\t\tConfiguration cfg = new Configuration();\r\n\t\tcfg.configure();\r\n\t\tSchemaExport se = new SchemaExport(cfg);\r\n\t\tse.create(true, true);\r\n\r\n\t\tSystem.out.println(\"Fim\");\r\n\t}\r\n\r\n\tprivate static SessionFactory sessionFactory = null;\r\n\tprivate static ServiceRegistry serviceRegistry;\r\n\r\n\tstatic {\r\n\t\ttry {\r\n\t\t\tsessionFactory = getSessionFactory();\r\n\t\t} catch (Throwable ex) {\r\n\t\t\tSystem.err.println(\"Initial SessionFactory creation failed.\" + ex);\r\n\t\t\tthrow new ExceptionInInitializerError(ex);\r\n\t\t}\r\n\t}\r\n\r\n\tpublic static SessionFactory getSessionFactory() {\r\n\t\tif (sessionFactory == null) {\r\n\t\t\tConfiguration configuration = new Configuration();\r\n\t\t\tconfiguration.configure();\r\n\t\t\tserviceRegistry = new ServiceRegistryBuilder().applySettings(\r\n\t\t\t\t\tconfiguration.getProperties()).buildServiceRegistry();\r\n\t\t\tsessionFactory = configuration.buildSessionFactory(serviceRegistry);\r\n\t\t\tsessionFactory.openSession();\r\n\t\t\treturn sessionFactory;\r\n\t\t}\r\n\t\treturn sessionFactory;\r\n\t}\r\n\r\n\tpublic static Session getSession() {\r\n\t\t\/\/ return sessionFactory.openSession();\r\n\t\treturn getSessionFactory().getCurrentSession();\r\n\t}\r\n}\r\n\r\n<\/pre>\n
\nNosso arquivo de configura\u00e7\u00e3o do Hibernate (hibernate.cfg.xml) tamb\u00e9m foi alterado e ficou assim:<\/p>\n\r\n\r\n\r\n\r\n
Conclus\u00e3o<\/H2><\/p>\n
\n Leia mais sobre EJB 3<\/a> que traz muitas facilidades no uso de CTM, mas tem que ser executado em um EJB container (JBoss\/WildFly, Websphere, WebLogic).
\n Como alternativa leia tamb\u00e9m sobre o uso do Framework Spring que tamb\u00e9m faz o controle de transa\u00e7\u00e3o jpa para nossa aplica\u00e7\u00e3o e tem a vantagem de rodar no Tomcat e nos EJB Containers.<\/p>\n
\n<\/p>\nLinks relacionados<\/H2>
\nConfigura\u00e7\u00e3o de acesso a console do servidor TOMCAT 8<\/a>
\nTomcat<\/a>
\nInstala\u00e7\u00e3o e configura\u00e7\u00e3o do TOMCAT<\/a>
\nCriar datasource no servidor Tomcat 8<\/a><\/p>\n