简体   繁体   中英

resource reference in EJB3

May be this is a common question, I am trying to create an Stateless session EJB 3.0 with resource reference for data source in Websphere 7.0.

The following code is working:

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>

The following code is not working and giving me excpetion

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

But not sure how to proceed when the Datasource needs to be looked up in initialContext out side of EJB.

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>

If I dont use "java:comp/env/" in data source lookup then it works fine, but that is not a good practice.

UPDATE: Thanks for the replies. My goal is to replace an existing EJB 2.1 to EJB 3.0. The current EJB 2.1 is designed similar to code snippet 2 so I wrote this test. EJB 2.1 is functioning with the resource defined out side of the ejb (but has the resource reference declared in ejb-jar.xml). If I dont follow the same approach then it will have a huge impact which I want to avoid.

You will have to use JNDI name(ie: java:comp/env/jdbc/myDataSource) of the resource residing in the server. JNDI name is a unique identifier of the resource. There is no other way whether it is a standalone java or container driven java. If you are using EJB then you can use annotations and refer the resource but still the resource will be looked up by your binding files where you have mentioned JNDI name. One way or the other, you will have to use JNDI name of the resource.

Answer Updated

If you are using EJB then just use annotation to access resource exactly what you have done first time. What you are doing is a bad practice. Because EJB is loaded and maintained in a container. There is no gaurantee that DataSource POJO will be loaded by class-loader before EJB makes a call to it. Both have different life cycles. So let the container inject the resource for you. It is the right practice. So EJB being dependent on a POJO is a bad practice. Not recommended in Java EE.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM