sqljdbc4驱动程序未从SQL Server 2012的上一次插入返回结果集

sqljdbc4驱动程序未从SQL Server 2012的上一次插入返回结果集,jdbc,sql-server-2012,spring-jdbc,Jdbc,Sql Server 2012,Spring Jdbc,我们的问题是,当从返回列表中的行集的SqlQuery类从SpringJDBC调用execute方法时,resultSet不会返回并引发异常。然而,插入发生得很好。我们发现,当我们使用Merlia驱动程序时,它是一个旧的驱动程序,甚至可以与SQL 2012一起使用。我认为我的配置不正确,因为sqljdbc4.jar驱动程序不适用于SQLServer2012,但适用于SQLServer2008。 我们看到的stacktrace是: com.microsoft.sqlserver.jdbc.SQLSe

我们的问题是,当从返回列表中的行集的SqlQuery类从SpringJDBC调用execute方法时,resultSet不会返回并引发异常。然而,插入发生得很好。我们发现,当我们使用Merlia驱动程序时,它是一个旧的驱动程序,甚至可以与SQL 2012一起使用。我认为我的配置不正确,因为sqljdbc4.jar驱动程序不适用于SQLServer2012,但适用于SQLServer2008。 我们看到的stacktrace是:

com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not return a result set.
com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:190)
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:408)
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:350)
com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696)
com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715)
com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:180)
com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:155)
com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:285)
org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:648)
org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:591)
org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:641)
org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:666)
org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:698)
org.springframework.jdbc.object.SqlQuery.execute(SqlQuery.java:112)
org.springframework.jdbc.object.SqlQuery.execute(SqlQuery.java:122)
ident.shared.dao.DAO.create(DAO.java:135)
ident.shared.business.BaseBusiness.create(BaseBusiness.java:57)
org.apache.jsp.add_005fnew_005fuser_jsp._jspService(add_005fnew_005fuser_jsp.java:538)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
顺便说一下,我确实尝试过将SpringJDBCJAR更新到至少3.1.4,但没有成功

我们已建立到SQl server 2012的JNDI连接。下面是context.xml中的一部分

 <Resource name="jdbc/Ident" auth="Container"
      type="javax.sql.DataSource"
      factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
      username="*****" password="*****"
      driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
      url="jdbc:sqlserver://*******\dev;databaseName=ident" 
      maxActive="50"
      maxIdle="10">
</Resource>
下面是从SpringJDBC插入和调用execute方法的代码。顺便说一下,IdQuery扩展了MappingSqlQuery,它扩展了org.springframework.jdbc.object.MappingSqlQueryWithParameters,而后者又扩展了SqlQuery,SqlQuery定义了IdQuery对象调用的执行方法

public DataObject create(DataObject data)
{       

    IdQuery idq = new IdQuery(dataSource, this);
    List idList = idq.execute(this.getCreateParameters(data));
    if (idList != null && idList.size() > 0 && !idList.get(0).equals(new Integer(0))) {
        data.setId((Integer)idList.get(0));
    }

    return data;
}
这是IdQuery的构造函数(如果有帮助的话)

class IdQuery extends MappingSqlQuery {

    IdQuery(DataSource ds, DAO dao) {
        super(ds,"somesql");
        dao.prepareCreate(this);
        super.setSql(this.getSql() + " SELECT SCOPE_IDENTITY() as ID");
        compile();
    }

    protected Object mapRow(ResultSet rs, int rowNum) throws SQLException {
        return (rs.getInt("ID"));
    }

}

那么,插入数据并尝试获取生成的密钥的代码在哪里呢?经过编辑以将该代码放入其中。这不是JDBC代码。您需要显示IdQuery.execute的功能,这样我们就可以检查它是否真正正确地使用了生成的密钥查询功能。您还需要包括异常的stacktrace。查看MappingSqlQuery的定义,我不认为它旨在执行生成的键查询。因此,它可能会尝试获取不存在的正常结果集,而不是生成的键结果集。将select连接到现有查询可能是问题的最大部分,尽管我预计会出现不同的异常。我建议您使用标准JDBC工具来检索生成的密钥,而SpringJDBC至少需要使用@jcd,您可能需要添加一个;然而,在两个查询之间——查看JDBC规范——单个语句execute应该只执行一个语句。问题还可能在于从服务器返回的更新计数和结果集的顺序可能是2012返回更新计数->结果集,其中2008返回结果集->更新计数,但这只是推测。
public DataObject create(DataObject data)
{       

    IdQuery idq = new IdQuery(dataSource, this);
    List idList = idq.execute(this.getCreateParameters(data));
    if (idList != null && idList.size() > 0 && !idList.get(0).equals(new Integer(0))) {
        data.setId((Integer)idList.get(0));
    }

    return data;
}
class IdQuery extends MappingSqlQuery {

    IdQuery(DataSource ds, DAO dao) {
        super(ds,"somesql");
        dao.prepareCreate(this);
        super.setSql(this.getSql() + " SELECT SCOPE_IDENTITY() as ID");
        compile();
    }

    protected Object mapRow(ResultSet rs, int rowNum) throws SQLException {
        return (rs.getInt("ID"));
    }

}