2014年5月14日星期三

About java.sql.SQLException: Closed Resultset: next unusual problem

This is a link I wrote a project , a utility class database operations ,


public class BaseDao {
   protected Connection conn=null;
   protected PreparedStatement ps=null;
   protected Statement stmt=null;
   protected ResultSet rs=null;
   public boolean getConnection(){
   //读出配置信息
   String driver=ConfigManager.getInstance().getString("jdbc.driver_class");
   String url=ConfigManager.getInstance().getString("jdbc.connection.url");
   String username=ConfigManager.getInstance().getString("jdbc.connection.username");
   String password=ConfigManager.getInstance().getString("jdbc.connection.password");
   //加载JDBC驱动   
try {  Class.forName(driver);
//与数据库建立连接
conn=DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return false;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
   return true;   
   }
   //增删改操作
   public int executeUpdate(String sql,Object[] params){
   int updateRows=0;
   getConnection();
   try {
ps=conn.prepareStatement(sql);
//填充占位符
for(int i=0;i<params.length;i++){
ps.setObject(i+1, params[i]);
}
//System.out.println(sql);
updateRows=ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
closeResource();
}
  return updateRows; 
   }
   //查询操作
   public ResultSet executeSQL(String sql,Object[] params){
   getConnection();
   try {
ps=conn.prepareStatement(sql);
//填充占位符
for(int i=0;i<params.length;i++){
ps.setObject(i++, params[i]);
}
rs=ps.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}finally{
closeResource();

  return rs; 
   }
   //关闭资源
   public boolean closeResource(){
   if(rs!=null){
   try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
   }
   if(ps!=null){
   try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
   }
   if(conn!=null){
   try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
   }
   return true;
   }
}

Here is what I wrote a class that implements the interface


public class BookDaoImpl extends BaseDao implements BookDao {
//获取图书列表
@Override
public List<Book> getBookList() {
List<Book> bookList=new ArrayList<Book>();
try {
//获得Statement对象,执行SQL语句
String sql="select * from books";
Object[] params={};
ResultSet rs=this.executeSQL(sql, params);
//处理执行结果(ResultSet)
while(rs.next()){
System.out.println("运行到这了吗");
int bid =rs.getInt("bid");
String bookname=rs.getString("bookname"); 
String b_price=rs.getString("b_price");   
String image=rs.getString("image"); 
int stock=rs.getInt("stock");
//将图书信息封装成对象
Book book=new Book();
book.setBid(bid);
book.setBookName(bookname);
book.setPrice(b_price);
book.setImage(image);
book.setStock(stock);
//将图书对象放进集合中
bookList.add(book);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
this.closeResource();
}
return bookList;
}
}

Here is a test of my class when I run this class is always reported the following exception

 public static void main(String[] args) {
BookDaoImpl bookDao=new BookDaoImpl();
 List<Book> bookList=bookDao.getBookList();
    for(Book book:bookList){
   System.out.println(book.getBid()+"\t"+book.getBookName()+"\t"+book.getPrice()+"\t"+book.getStock());
   }

anomaly investigation said a lot of information is multi-threaded concurrency issues , but I just do not know where it appeared , seeking Great God help ah !

 java.sql.SQLException: 关闭的 Resultset: next
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.driver.OracleResultSetImpl.next(OracleResultSetImpl.java:175)
at com.bdqn.OA.Dao.Impl.BookDaoImpl.getBookList(BookDaoImpl.java:37)
at com.bdqn.OA.Dao.Impl.BookDaoImpl.main(BookDaoImpl.java:223)


------ Solution ------------------------------------ --------
your BookDaoImpl how to inherit a BookDao and achieve a BookDao?
ResultSet rs = this.executeSQL (sql, params);
executeSQL way you have to call the parent class closeResource (); method
that is, you call rs.next () before , has closed ResultSet!
so we wrong !
------ Solution ---------------------------------------- ----
executeSQL calls to close the ResultSet
------ Solution --------------------------- -----------------
Yes, you BaseDao in the parent class method in a query executeSQL not directly close closeResource (); is not the first to write finally, since the use resultset he was disconnected once and databases , data sets where the data is also gone, but there are finally in the subclass method, so the parent class can save
------ Solution ----- ---------------------------------------

floor to explain it place
------ For reference only ------------------------------------- -
your BookDaoImpl how to inherit a BookDao and achieve a BookDao?
ResultSet rs = this.executeSQL (sql, params);
executeSQL way you have to call the parent class closeResource (); method
that is, you call rs.next () before , has closed ResultSet!
so we wrong !

I inherited one of BookDaoImpl BaseDao and implement a BookDao
I now find the cause of the error , that is because I executeSQL BaseDao tool class and the executeUpdate method in the finally executed closeResource closed Rideau resource methods, making ResultSet was closed, very grateful to the four upstairs correction !

没有评论:

发表评论