[Resolvido] configurar JNDI > persistence-unit + hibernate + tomcat 6

Olá pessoal,

estou com um problema para configurar e fazer a conexão com a base de dados funcionar via JNDI…
o ambiente é:

  • Java 1.5
  • Apache Tomcat 6
  • Hibernate + JPA (persistence-unit)

a configuração do meu datasource para o tomcat:

<?xml version="1.0" encoding="UTF-8"?> <context path="/app" docBase="app" debug="5" reloadable="true" crossContext="true"> <Resource name="jdbc/app" auth="Container" type="javax.sql.DataSource" driverClassName="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@hostserv:1234:dbname" username="user_name" password="user_pass" maxActive="20" maxIdle="10" maxWait="-1"/> </context>

também adicionei no web.xml a config:

<resource-ref> <description>DB Oracle Application</description> <res-ref-name>jdbc/app</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>

e no WEB-INF/classes/META-INF/persistence.xml

<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="datasource" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:comp/env/jdbc/app</jta-data-source> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9iDialect" /> <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/> <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/> </properties> </persistence-unit> </persistence>

e na hora da execução ocorre o respectivo erro:

javax.persistence.PersistenceException: [PersistenceUnit: datasource] Unable to build EntityManagerFactory at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:677) at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:126) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:52) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:34) at br.com.gvt.cdi.dao.hibernate.base.DaoBase.getEntityManager(DaoBase.java:23) at br.com.gvt.cdi.dao.hibernate.LogDAO.save(LogDAO.java:122) at br.com.gvt.cdi.dao.hibernate.LogDAO.save(LogDAO.java:1) at br.com.gvt.cdi.bo.LogBO.save(LogBO.java:108) at br.com.gvt.cdi.bo.LogBO.logAcessoRetail(LogBO.java:51) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at flex.messaging.services.remoting.adapters.JavaAdapter.invoke(JavaAdapter.java:421) at flex.messaging.services.RemotingService.serviceMessage(RemotingService.java:183) at flex.messaging.MessageBroker.routeMessageToService(MessageBroker.java:1495) at flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:882) at flex.messaging.endpoints.amf.MessageBrokerFilter.invoke(MessageBrokerFilter.java:121) at flex.messaging.endpoints.amf.LegacyFilter.invoke(LegacyFilter.java:158) at flex.messaging.endpoints.amf.SessionFilter.invoke(SessionFilter.java:44) at flex.messaging.endpoints.amf.BatchProcessFilter.invoke(BatchProcessFilter.java:67) at flex.messaging.endpoints.amf.SerializationFilter.invoke(SerializationFilter.java:146) at flex.messaging.endpoints.BaseHTTPEndpoint.service(BaseHTTPEndpoint.java:278) at flex.messaging.MessageBrokerServlet.service(MessageBrokerServlet.java:315) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) at java.lang.Thread.run(Thread.java:595) Caused by: org.hibernate.HibernateException: Could not locate TransactionManager at org.hibernate.transaction.JNDITransactionManagerLookup.getTransactionManager(JNDITransactionManagerLookup.java:60) at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:357) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1327) at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867) at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669) ... 36 more Caused by: javax.naming.NameNotFoundException: Name TransactionManager is not bound in this Context at org.apache.naming.NamingContext.lookup(NamingContext.java:770) at org.apache.naming.NamingContext.lookup(NamingContext.java:153) at org.apache.naming.SelectorContext.lookup(SelectorContext.java:137) at javax.naming.InitialContext.lookup(InitialContext.java:351) at org.hibernate.transaction.JNDITransactionManagerLookup.getTransactionManager(JNDITransactionManagerLookup.java:57) ... 40 more javax.persistence.PersistenceException: [PersistenceUnit: datasource] Unable to build EntityManagerFactory

o que me intriga é : Caused by: org.hibernate.HibernateException: Could not locate TransactionManager

caso alguém tiver alguma idéia, link, material sobre o assunto é muito bem vindo…

obs.: no Google e aqui no forum não localizei nenhum material que me ajudou a solucionar o problema :frowning:

teoricamente para mim está resolvido esse problema no Apache Tomcat 6

o que eu fiz:

criei o hibernate.properties e adicionei:

e na classe onde eu pego o persistence-unit na linha acima adicionei:

também fiz uma alteração do META-INF/persistence.xml para:

[code]

<persistence-unit name="datasource">
	<properties>
		<property name="hibernate.connection.datasource" value="java:comp/env/jdbc/app"/>
		<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9iDialect" />			
	</properties>
</persistence-unit>	

[/code]

com isto começou a funcionar a conexão através do JNDI…
fiz um teste de remover o hibernate.properties e a linha que adicionei no código java, feito isso
o erro anterior ocorre novamente…

ps.: não sei explicar o motivo desse comportamento…

agora vou testar esse formato no Weblogic 9, ver se funciona assim também…

Update: esta mesma solução funcionou…

criei o datasource no Weblogic 9 e realizei o deploy da mesma versão do .war da aplicação no servidor,
onde funcionou sem problemas :smiley:

&lt;property name="hibernate.transaction.manager_lookup_class"  value=""/&gt;  

Tem como esta propriedade funcionar no TomCat? Ela é importante para utilização do second level cache. Eu implementei um semáforo via JNDI, para garantir acesso único aos arquivos do cache. Eu ainda tenho dúvida se somente o JTA do Hibernate é suficiente e se é mesmo necessário colocar um semáforo.

criei uma classe factory para iniciar o JNDI e outra para segurar o semáforo.

/**********************************************************
TRANSACTION FACTORY
**********************************************************/
package rwk.farolet;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
public class TransactionFactory implements ObjectFactory{
  /*=======================================================

  =======================================================*/
  public TransactionFactory(){
    System.out.println(&quot;TransactionFactory:start&quot;);
  }
  /*=======================================================

  =======================================================*/
  public Object getObjectInstance(Object obj,Name name,Context nameCtx,Hashtable&lt;?,?&gt; environment) throws Exception{
    return Transaction.getInstance();
  }
}

/**********************************************************
TRANSACTION
**********************************************************/
package rwk.farolet;

import java.util.concurrent.Semaphore;

public class Transaction{
  private static Semaphore semaphore=new Semaphore(1,true);
  private static Instance instance=new Instance(new Transaction());
  /*=======================================================

  =======================================================*/
  public Semaphore getSemaphore(){
    return semaphore;
  }
  /*=======================================================

  =======================================================*/
  public Transaction(){
    System.out.println(&quot;Farolet:Transaction:Start:&quot;+this);
  }
  /*=======================================================

  =======================================================*/
  public static Transaction getInstance(){
    return(Transaction)instance.getInstance();
  }
}
class Instance{
  private Object instance;
  public Instance(Object o){this.instance=o;}
  public Object getInstance(){return instance;}
  public void setInstance(Object instance){this.instance=instance;}
}

No arquivo do tomcat conf/context.xml

&lt;?xml version='1.0' encoding='utf-8'?&gt;

&lt;Context&gt;
  &lt;WatchedResource&gt;WEB-INF/web.xml&lt;/WatchedResource&gt;
  &lt;Resource name="rwk/Transaction" auth="Container" type="rwk.farolet.Transaction" factory="rwk.farolet.TransactionFactory"/&gt;
&lt;/Context&gt;

Será que tem algum problema esta implementação?
Será que tem alguma solução implementada de JTA para TomCat?