SessionBean调用数据库的问题

03-08-20 trainking
我想试验一下用SessionBean调用数据库,因此写了以下程序:

deleteEJBBean.java:

package MydeleteEJB;

import java.rmi.RemoteException;

import java.sql.*;

import javax.ejb.*;

import javax.sql.*;

import javax.naming.*;

public class deleteEJBBean implements SessionBean

{String Driver="org.gjt.mm.mysql.Driver";

String URL="jdbc:mysql://localhost:3306/CustomerDB";

String user="root";

String password="java123";

private Connection con;

private SessionContext context;

public void deleteRecord(int ssn)

{

rs=null;

try {

Statement smt=con.createStatement();

ResultSet rs=smt.executeQuery("select * from customer");

rs.absolute(ssn);

rs.deleteRow();

System.out.println("OK");

}

catch(Exception e)

{System.out.println("wrong");

e.printStackTrace();}

}

public deleteEJBBean(){}

public void ejbCreate()throws CreateException{

String selectStatement="SELECT * FROM customer";

try{

makeConnection();

}

catch(Exception e)

{throw new CreateException(e.getMessage());}

}

public void ejbRemove(){

try{

con.close();

}

catch(SQLException ex){

throw new EJBException(ex.getMessage());

}

}

public void ejbActivate(){

try{

makeConnection();

}

catch(Exception ex){

throw new EJBException(ex.getMessage());

}}

public void ejbPassivate(){

try{

con.close();

}

catch(SQLException ex){

throw new EJBException(ex.getMessage());

}}

public void setSessionContext(SessionContext sc){

this.context=sc;}

private void makeConnection() throws NamingException,SQLException{

try{

Class.forName(Driver);

}

catch(Exception e){System.out.println("cannot load driver:"+Driver);

e.printStackTrace();}

try{

Connection con=DriverManager.getConnection(URL,user,password);

if(!con.isClosed())System.out.println("Open success!");

}

catch(SQLException SE){System.out.println("Open Failed");

SE.printStackTrace();}

}

}

调用该SessionBean的Servlet如下:

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import javax.ejb.FinderException;

import javax.naming.*;

import javax.rmi.PortableRemoteObject;

import java.rmi.RemoteException;

import javax.ejb.CreateException;

import MydeleteEJB.deleteEJB;

import MydeleteEJB.deleteEJBHome;

public class deleteServlet extends HttpServlet{

deleteEJBHome home=null;

public void init() throws ServletException{

try{

InitialContext ic=new InitialContext();

Object objref=ic.lookup("MydeleteEJB");

home=(deleteEJBHome)PortableRemoteObject.narrow(objref,deleteEJBHome.class);

}

catch(Exception e){

e.printStackTrace();

throw new ServletException(e.getMessage());

}

}

public void doPost(HttpServletRequest req,HttpServletResponse res)

throws ServletException,IOException

{res.setContentType("text/html;charset=GBK");

PrintWriter out=res.getWriter();

if(req.getParameterValues("strtext")!=null)

{String str=req.getParameter("strtext");

int ssn=Integer.parseInt(str);

try{

deleteEJB dl=home.create();

out.println("You have done home.create()");

dl.deleteRecord(ssn);

out.println("You have done deleteRecord()");

}

catch(Exception e){out.println("call EJB wrong");

e.printStackTrace();}

out.println("You have deleted the record:"+str);

}

else

out.println("Parameter is null");

}

}

运行后,Servlet页面显示:

You have done home.create() You have done deleteRecord() You have deleted the record:1好像没有错

但是WebLogic的DOS界面中显示:

Open success!

wrong

java.lang.NullPointerException

at MydeleteEJB.deleteEJBBean.deleteRecord(deleteEJBBean.java:30)

at ydeleteEJB.deleteEJBBean_5xkxu6_EOImpl.deleteRecord(deleteEJBBean_5x

kxu6_EOImpl.java:36)

at MydeleteEJB.deleteEJBBean_5xkxu6_EOImpl_WLSkel.invoke(Unknown Source)

at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:288)

at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:257)

at weblogic.rmi.internal.BasicServerRef.dispatch(BasicServerRef.java:158)

at weblogic.rmi.internal.ServerRequest.sendOneWayRaw(ServerRequest.java:92)

at weblogic.rmi.internal.ServerRequest.sendReceive(ServerRequest.java:112)

at weblogic.rmi.internal.BasicRemoteRef.invoke(BasicRemoteRef.java:133)

at weblogic.rmi.internal.ProxyStub.invoke(ProxyStub.java:35)

at $Proxy89.deleteRecord(Unknown Source)

at deleteServlet.doPost(deleteServlet.java:42)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)

at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:263)

at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:200)

at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppSe

rvletContext.java:2390)

at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestIm

pl.java:1959)

at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:137)

at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:120)

这样的话,就是我EJB中的Statement smt=con.createStatement();一句出错了。但我看了很久,也不知道为什么这里会出错,我这些语句我以前写在一般的java程序中都是正确的呀。

希望大家帮我看看,到底哪里出错了。谢谢!

robbin
2003-08-20 11:56
打击一下你,且不论你的这个错误,你的EJB写的完全不对。在EJB中禁止使用DriverManager的方式获得Connection,DriverManager是单线程的。即使使用连接池也必须使用App Server提供的连接池,不能使用第三方连接池,否则将无法使用容器管理事务。

trainking
2003-08-20 15:04
哦,是这样啊。

我倒是的确没看到哪本书上是像我这样做的:)

我看到书上经常是这样的:

……

String dbName="java:comp/env/jdbc/CustomerDB";

……

InitialContext ic=new InitialContext();

DataSource ds=(DataSource)ic.lookup(dbName);

con=ds.getConnection();

这样的连接方式应该没错吧。

可是我没有看懂。

首先:"java:comp/env/jdbc/CustomerDB"是什么意思?这是个什么路径,在哪里设的?

其次:这样连接,为什么没有加载驱动程序的语句?

最后:我要不要在配置文件中写什么关于数据库连接或者其他和数据库相关的描述?在WebLogic的控制台中要不要配置什么?

恳请Robbin再为我解释一下吧,谢谢!

robbin
2003-08-20 18:14
>>"java:comp/env/jdbc/CustomerDB"是什么意思?这是个什么路径,在哪里设的?<<

DataSource的JNDI名称,应该是在App Server上配置

>>这样连接,为什么没有加载驱动程序的语句?<<

配置DataSource的时候已经指定了

>>我要不要在配置文件中写什么关于数据库连接或者其他和数据库相关的描述?在WebLogic的控制台中要不要配置什么?<<

http://edocs.bea.com/wls/docs81/ConsoleHelp/jdbc_connection_pools.html

先要把JDBC驱动加到startWelogic.cmd的CLASSPATH里面,然后启动Weblogic,在Console控制台配置DataSource。

trainking
2003-08-22 15:13
谢谢robbin,现在可以了。

但是有一点我不明白。既然EJB禁止使用DriverManager方式获得Connection,那么为什么编译时没有报错,并且,如果只进行数据库连接操作的话,我上面的那段程序运行后也没有报错呢?

猜你喜欢