2013-04-10 53 views
0

可能這是一個常見問題,我試圖創建一個無狀態會話EJB 3.0,其中包含Websphere 7.0中數據源的資源引用。EJB3中的資源引用

下面的代碼工作:

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中聲明瞭資源引用)。如果我不遵循同樣的方法,那麼它將會產生我想要避免的巨大影響。

回答

0

您將不得不使用駐留在服務器中的資源的JNDI名稱(即:java:comp/env/jdbc/myDataSource)。 JNDI名稱是資源的唯一標識符。無論是獨立的Java還是容器驅動的Java,都沒有其他方法。如果您使用的是EJB,那麼您可以使用註釋並引用該資源,但仍然會在您提到的JNDI名稱的綁定文件中查找該資源。無論如何,您將不得不使用資源的JNDI名稱。

答案如果您正在使用EJB,只需使用註釋訪問資源正是你所做的第一次更新

。你在做什麼是一個不好的做法。因爲EJB是在一個容器中加載和維護的。在EJB調用它之前,DataSource POJO將不會被類加載器加載。兩者都有不同的生命週期。所以讓容器爲你注入資源。這是正確的做法。所以EJB依賴於POJO是一種不好的做法。不推薦在Java EE中使用。

+0

感謝您的答覆。我同意我必須使用JNDI名稱,但不知道如何在我的第二段代碼中執行此操作。 – user2104750

+0

如果您使用的是EJB,那麼只需使用註釋就可以完全訪問您第一次完成的工作。你在做什麼是一個不好的做法。因爲EJB是在一個容器中加載和維護的。在EJB調用它之前,DataSource POJO將不會被類加載器加載。兩者都有不同的生命週期。所以讓容器爲你注入資源。這是正確的做法。所以EJB依賴於POJO是一種不好的做法。不建議在J2EE中使用。問候,拉維。 –

0

替換@Resource@Resource(name="jdbc/myDataSource")它應該工作。

+0

帶註釋的代碼運行良好,問題在於查找EJB外部的數據源的第二段代碼... – user2104750

+0

是的,並且更改註釋將確保JNDI名稱是您期望的其他代碼段中的內容。 –

+0

我很抱歉,我不確定你要求我替換註釋。在代碼片段2中,我僅使用了@Stateless註釋。如果可能,您可以向我提供代碼嗎? – user2104750