0

可能这是一个常见问题,我正在尝试使用 Websphere 7.0 中数据源的资源引用创建无状态会话 EJB 3.0。

以下代码正在工作:

package com;
import javax.ejb.Stateless;
import javax.annotation.Resource;
import javax.sql.DataSource;
@Stateless
public class Test1 implements Test1Remote {
 @Resource DataSource ds;
 public Test1() {}
 public boolean testDs() {
  boolean valid = true;
  try {
   ds.getConnection();
  } catch (Exception e) {
   e.printStackTrace();
   valid = true;
  }
  return valid;
 }
}


<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar-bnd
    xmlns="http://websphere.ibm.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee 
    http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd" version="1.0">

    <session name="Test1">
     <interface class="com.Test1Remote" binding-name="Test1"/>
     <resource-ref name="com.Test1/ds" binding-name="jdbc/myDataSource"></resource-ref>
    </session>
</ejb-jar-bnd>

以下代码不起作用,并给了我异常

javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "java:".

但不确定当需要在 EJB 之外的 initialContext 中查找数据源时如何进行。

package com;
import javax.ejb.Stateless;
@Stateless
public class Test1 implements Test1Remote {
    public Test1() {
    }
    public boolean testDs(){
     boolean valid = true;
     try {
         MyConnection ds = new MyConnection();
         ds.getConnection();
     } catch (Exception e) {
        e.printStackTrace();
        valid = true;
    }
    return valid;
    }
}

package com;
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;


public class MyConnection{
    private DataSource ds;
    public Object getConnection() throws Exception  {
 try {
    final InitialContextinitCtx = new InitialContext();
    ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/myDataSource");
    return ds.getConnection();
    } catch (NamingException e) {
     e.printStackTrace();
     throw e;
    } catch (SQLException e) {
     e.printStackTrace();
     throw e;
    }
 }
}

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar-bnd
    xmlns="http://websphere.ibm.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee 
    http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd" version="1.0">

    <session name="Test1">
     <interface class="com.Test1Remote" binding-name="Test1"/>
    </session>
</ejb-jar-bnd>

如果我在数据源查找中不使用“java:comp/env/”,那么它可以正常工作,但这不是一个好习惯。

更新:感谢您的回复。我的目标是将现有的 EJB 2.1 替换为 EJB 3.0。当前的 EJB 2.1 的设计类似于代码片段 2,所以我编写了这个测试。EJB 2.1 使用在 ejb 之外定义的资源运行(但在 ejb-jar.xml 中声明了资源引用)。如果我不遵循相同的方法,那么它将产生我想避免的巨大影响。

4

2 回答 2

0

Replace @Resource with @Resource(name="jdbc/myDataSource") and it should work.

于 2013-04-11T16:46:04.793 回答
0

您将不得不使用驻留在服务器中的资源的 JNDI 名称(即:java:comp/env/jdbc/myDataSource)。JNDI 名称是资源的唯一标识符。无论是独立的 java 还是容器驱动的 java,都没有其他办法。如果您使用的是 EJB,那么您可以使用注释并引用资源,但仍然会在您提到 JNDI 名称的绑定文件中查找该资源。无论哪种方式,您都必须使用资源的 JNDI 名称。

答案已更新

如果您使用的是 EJB,那么只需使用注释来访问您第一次所做的资源。你正在做的是一个不好的做法。因为 EJB 是在容器中加载和维护的。没有保证 DataSource POJO 将在 EJB 调用它之前由类加载器加载。两者都有不同的生命周期。所以让容器为你注入资源。这是正确的做法。因此,EJB 依赖于 POJO 是一种不好的做法。在 Java EE 中不推荐。

于 2013-04-11T13:15:53.093 回答