java.lang.ClassCastException,通过JNDI查找获取Entitymanager

时间:2014-10-23 10:36:50

标签: java tomcat jpa jdbc jndi

我是JPA的新手并开发了一个webapp(J2EE),其中webapp在Tomcat中,所以我不能使用@PersistenceContext。我决定使用Helper课程,一切都很顺利。然后我决定为连接池实现JNDI,并设法获得Datasource。

Helper Class如下所示:

try {
    Context initCtx = new InitialContext();
    entityManager =                                   //class cast exception
        (EntityManager)initCtx.lookup(
            "java:/comp/env/jdbc/LCDS"
        );
    DataSource ds= (DataSource)initCtx.lookup(
            "java:/comp/env/jdbc/LCDS"
    ); 
    System.out.println(ds.getConnection()+"Cool");
    //jdbc:mysql://localhost:3306/XXXXXXX, UserName=root@localhost, MySQL-AB JDBC  DriverCool
    emf=(EntityManagerFactory) source.getConnection();      //class cast exception
    emf = Persistence.createEntityManagerFactory("XXXX");   //working version
} 

错误是:

ava.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.BasicDataSource cannot be cast to javax.persistence.EntityManager

我不知道我哪里出错了。我无法通过JNDI查找获取EntityManagerFactory或EntityManager。我试过@Resource(name =“jdbc / LCDS”)和@PersistenceUnit(name =“jdbc / LCDS”)。

2 个答案:

答案 0 :(得分:0)

<强>更新
由于Tomcat的限制,JNDI无法访问持久性单元。见JPA Tomcat limitations。您必须使用emf = Persistence.createEntityManagerFactory("UNIT NAME") 对不起误导性的回答。我在WebSphere Liberty上测试过,没有Tomcat。

如果您需要该功能,请检查WebSphere Liberty,它与Tomcat一样快速且轻量级,但完全符合Java EE Web配置文件。它有许多有用的功能,如JPA,EJBLite,JAX-RS,如果需要已经可用,而不需要与额外的库配置作斗争。

更新结束

我已检查过WebSphere Liberty,您需要创建引用以通过JNDI查找持久性单元。您有两种方法可以创建它:

  • 在班级使用注释
    在任何servlet中,您需要使用follownig定义注释:
  

@PersistenceUnit(name="JPATestRef", unitName="UnitName")
    public class JPATester extends HttpServlet {
     ...

  • 使用web.xml
  • 中的条目
<persistence-unit-ref>
  <persistence-unit-ref-name>JPATestRef</persistence-unit-ref-name>
  <persistence-unit-name>UnitName</persistence-unit-name>
</persistence-unit-ref>

然后使用以下代码访问它:

try {
    InitialContext ctx = new InitialContext();
    System.out.println("looking EntityManagerFactory:");
    EntityManagerFactory emf2 = (EntityManagerFactory) ctx.lookup("java:comp/env/JPATestRef");
    System.out.println("emf:2" + emf2);

} catch (NamingException e) {

答案 1 :(得分:0)

要在JPA中使用JNDI数据源,应在persistence.xml中指定,如:

    <persistence 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" version="2">
        <persistence-unit name="..." transaction-type="RESOURCE_LOCAL">
        <non-jta-data-source>java:/comp/env/jdbc/LCDS</non-jta-data-source>
    ...

然后你只需要通过Persistence#createEntityManagerFactory(String)创建你的EntityManagerFactory。如果要回收EntityManagerFactory,这应该在JNDI之外完成(例如,作为ServletContext属性)。这是因为Tomcat不是Java EE服务器,只是一个servlet容器:他无法注入持久性单元。