Websphere EJB3中的资源引用

Websphere EJB3中的资源引用,websphere,ejb-3.0,resourcereference,Websphere,Ejb 3.0,Resourcereference,可能这是一个常见的问题,我正在尝试创建一个无状态会话EJB3.0,其中包含WebSphere7.0中数据源的资源引用 以下代码正在运行: package-com; 导入javax.ejb.Stateless; 导入javax.annotation.Resource; 导入javax.sql.DataSource; @无国籍 公共类Test1实现Test1Remote{ @资源数据源ds; 公共Test1(){} 公共布尔testDs(){ 布尔有效=真; 试一试{ ds.getConnectio

可能这是一个常见的问题,我正在尝试创建一个无状态会话EJB3.0,其中包含WebSphere7.0中数据源的资源引用

以下代码正在运行:

package-com;
导入javax.ejb.Stateless;
导入javax.annotation.Resource;
导入javax.sql.DataSource;
@无国籍
公共类Test1实现Test1Remote{
@资源数据源ds;
公共Test1(){}
公共布尔testDs(){
布尔有效=真;
试一试{
ds.getConnection();
}捕获(例外e){
e、 printStackTrace();
有效=真;
}
返回有效;
}
}


下面的代码不起作用,给了我解释

javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "java:".
但不确定当需要在EJB外部的initialContext中查找数据源时如何继续

package-com;
导入javax.ejb.Stateless;
@无国籍
公共类Test1实现Test1Remote{
公共测试1(){
}
公共布尔testDs(){
布尔有效=真;
试一试{
MyConnection ds=新的MyConnection();
ds.getConnection();
}捕获(例外e){
e、 printStackTrace();
有效=真;
}
返回有效;
}
}
包装组件;
导入java.sql.Connection;
导入java.sql.SQLException;
导入javax.naming.InitialContext;
导入javax.naming.NamingException;
导入javax.sql.DataSource;
公共类MyConnection{
私有数据源ds;
公共对象getConnection()引发异常{
试一试{
final InitialContextinitCtx=新的InitialContext();
ds=(DataSource)initCtx.lookup(“java:comp/env/jdbc/myDataSource”);
返回ds.getConnection();
}捕获(NamingE例外){
e、 printStackTrace();
投掷e;
}捕获(SQLE异常){
e、 printStackTrace();
投掷e;
}
}
}
如果我在数据源查找中不使用“java:comp/env/”,那么它可以正常工作,但这不是一个好的实践


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

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

答案更新


若您使用的是EJB,那个么只需使用注释来访问资源,就像您第一次做的那个样。你所做的是一种坏习惯。因为EJB是在容器中加载和维护的。在EJB调用数据源POJO之前,类加载器不会加载数据源POJO。两者都有不同的生命周期。因此,让容器为您注入资源。这是正确的做法。因此EJB依赖于POJO是一种糟糕的做法。不建议在Java EE中使用。

@Resource
替换为
@Resource(name=“jdbc/myDataSource”)
,它应该可以工作。

感谢您的回复。我同意我必须使用JNDI名称,但我不知道如何在我的第二段代码中实现这一点,如果您使用的是EJB,那么只需使用注释来访问资源,就像您第一次做的一样。你所做的是一种坏习惯。因为EJB是在容器中加载和维护的。在EJB调用数据源POJO之前,类加载器不会加载数据源POJO。两者都有不同的生命周期。因此,让容器为您注入资源。这是正确的做法。因此EJB依赖于POJO是一种糟糕的做法。在J2EE中不推荐使用。注意,Ravi。带注释的代码运行良好,问题在于第二段代码在EJB之外查找数据源……是的,更改注释将确保JNDI名称与您在其他代码段中期望的相同。对不起,我不确定您要我在哪里替换注释。在代码片段2中,我只使用了@Stateless注释。如果可能的话,你能提供给我代码吗?如果你想完全摆脱注入,那么你需要创建一个ejb-jar.xml部署描述符并在那里声明资源引用(就像你在EJB2.1中所做的那样)。