Результаты не могут быть получены из CallableStatement до его выполнения - PullRequest
0 голосов
/ 19 июля 2011

У меня есть этот метод в моем приложении, чтобы получить дочерние организации определенной организации.Он вызывает хранимую процедуру (которая создает временную таблицу).

StoredProcedureDAO.java

private Connection dbConnection = null;
private CallableStatement cstmt = null;
private ResultSet results = null;

внутри метода getChildrens (int siteId)

public ArrayList<String> getChildrens(int siteId)
{
    ArrayList<String> childrenSites = new ArrayList<String>();
    Connection pgConnection = getFreshDBConnection();
    if (pgConnection == null) {
        cat.error("getChildrens got a null connection");
        return null;
    }
    try{            
        pgConnection.setAutoCommit(false);
        cstmt = pgConnection.prepareCall("{ ? = call \"spGetChildSitesInfo\" ( ? ) }");
        cstmt.registerOutParameter(1, Types.OTHER);
        cstmt.setInt(2, siteId);
        cstmt.execute();
        results = (ResultSet) cstmt.getObject(1);
        if(results != null){
            while(results.next()){
                childrenSites.add(results.getString(1));
            }
        }
        cstmt.close();
        pgConnection.commit();
        pgConnection.close();
    } catch (SQLException e){
        try {
            pgConnection.rollback();
            cat.error("SQL Exception has occured while retriving the children", e);
        } catch (Exception ex) {
            cat.error("Error while connection rollback: ", e);
        }

    } finally {
        try {
            if(!pgConnection.isClosed()){
                pgConnection.setAutoCommit(true);
                pgConnection.close();
            }
            pgConnection = null;
        } catch (Exception e) {
            cat.error("Error while closing the connection: "+e);
        }
    }

    return childrenSites;
}

Я вызываю эту функцию при нажатии на ссылку в моем jsp, и все работает отлично. Проблема возникает, когда я нажимаю на ссылку более одного раза между действиями.В этом случае я получаю следующее исключение

ERROR [StoredProcedureDAO] SQL Exception has occured while retriving the children
org.postgresql.util.PSQLException: Results cannot be retrieved from a CallableStatement before it is executed.
    at org.postgresql.jdbc2.AbstractJdbc2Statement.checkIndex(AbstractJdbc2Statement.java:2417)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.checkIndex(AbstractJdbc2Statement.java:2400)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.getObject(AbstractJdbc2Statement.java:2084)
    at com.mycompany.ejb.session.StoredProcedureDAO.getChildrens(StoredProcedureDAO.java:120)
    at com.mycompany.struts.action.SessionFacadeManager.getSelectedSite(SessionFacadeManager.java:495)
    at org.apache.jsp.Clinical.BrowseCases_jsp._jspService(BrowseCases_jsp.java:383)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:373)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:336)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:654)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:445)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:379)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:292)
    at org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.java:1069)
    at org.apache.struts.action.RequestProcessor.processForwardConfig(RequestProcessor.java:455)
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:279)
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
    at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:507)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:524)
    at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
    at java.lang.Thread.run(Thread.java:619)

Добавление дополнительной информации после экспериментов

Это мой конструктор (приватный)

private StoredProcedureDAO() {
        DBManager dbManager = DBManager.getInstance();
        dbConnection = dbManager.getConnection();
    }

Ивот getInstance ()

public static StoredProcedureDAO getInstance()
    {
        if (myself == null)
            myself = new StoredProcedureDAO();
        return myself;
    }

Я вызываю getChildrens () с использованием следующего

StoredProcedureDAO dao = StoredProcedureDAO.getInstance();
children = dao.getChildrens(site_id);

Теперь, если я удалю оператор if

//if (myself == null)

в этом случае я не получаю исключения.Я использую драйвер postgresql-9.0-801.jdbc4.jar.Кто-нибудь может объяснить мне причину?

Ответы [ 3 ]

2 голосов
/ 19 июля 2011

У вас проблема с многопоточностью. Кажется, что вы разделяете переменные-члены ResultSet между разными потоками (сервлет (или JSP) может совместно использоваться несколькими потоками), отсюда и ошибка. Вы уверены, что создаете несколько экземпляров StoredProcedureDAO?

1 голос
/ 19 июля 2011

Проблема заключается в совместном использовании не поточно-ориентированных ресурсов между потоками.Перестаньте пытаться управлять всеми ресурсами базы данных вручную, и используйте инфраструктуру , такую ​​как Spring, чтобы справиться со всем этим за вас.Это спасет вас от себя.

0 голосов
/ 19 июля 2011

Вы должны закрыть Результат в конечном итоге. Вы можете попробовать его.

...