我使用的是liferay(与tomcat 7.0.23捆绑在一起的6.1.0)portlet,它使用不同于liferay db的自己的数据库。
好吧,如果我通过tomcat连接池访问数据库它可以正常工作
String jndiName = "java:/comp/env/jdbc/myDB";
try {
Context ctxt = new InitialContext();
Name name = ctxt.getNameParser( "" ).parse( jndiName);
DataSource ds = (DataSource) ctxt.lookup( name ); //I've got the DataSource
} catch (NamingException e) {
System.out.println("[NamingException]");
}
如果我使用JPA(由Hibernate 4实现),它会抛出NamingException。 这是我的persistence.xml
<persistence version="2.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_2_0.xsd">
<persistence-unit name="myPU">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<non-jta-data-source>java:/comp/env/jdbc/myDB</non-jta-data-source>
<properties>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
这是我的(简单)代码
EntityManagerFactory emf=Persistence.createEntityManagerFactory("myPU");
EntityManager em=emf.createEntityManager();
这是stacktrace的相关部分
Caused by: org.hibernate.engine.jndi.JndiException: Unable to lookup JNDI name [java:/comp/env/jdbc/myDB]
at org.hibernate.engine.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:117)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.configure(DatasourceConnectionProviderImpl.java:115)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111).
好吧,我下载了hibernate源代码,这是org.hibernate.engine.jndi.internal.JndiServiceImpl类的代码片段
public Object locate(String jndiName) {
final InitialContext initialContext = buildInitialContext();
final Name name = parseName( jndiName, initialContext );
try {
return initialContext.lookup( name );
}
catch ( NamingException e ) {
throw new JndiException( "Unable to lookup JNDI name [" + jndiName + "]", e );
}
finally {
cleanUp( initialContext );
}
}
其中buildInitialContext()执行新的InitialContext()
所以,似乎hibernate和我做同样的事情,但是对于某些事情,InitialContext是不同的广告,所以hibernate的查找失败。
请记住,我的上下文是在TOMCAT_HOME / Catalina / localhost下定义的。 请记住,如果在persistence.xml中我不使用tomcat数据源但是放置连接参数......它可以工作!
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/mydb" />
<property name="javax.persistence.jdbc.user" value="myuser" />
<property name="javax.persistence.jdbc.password" value="mypwd" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
提前致谢