Oracle PreparedStatement - 一些开发人员的NullPointerException,但不是全部

时间:2016-05-04 03:43:51

标签: java database spring oracle prepared-statement

项目概述

我有一个具有以下属性的项目:

  • 数据库: Oracle 12c
    • 1桌: MY_TABLE
    • 2列:
      • ID: PK,VARCHAR2,32字节大小限制,默认值= SYS_GUID()
      • MY_OBJ:存储JSON对象以供将来使用
  • 应用程序框架/平台:Spring,Java 8u77

问题

我正在尝试运行以下预准备语句,该语句应输出新生成的插入对象的键/ ID。不幸的是,我不断得到与语句相关的NullPointerException。

奇怪的是,75%的团队遇到了同样的问题,而其他 25%的团队的代码工作得很好

问题

为什么以下代码在一台计算机上正常运行,但在其他计算机上返回错误?

如何在所有机器上完成这项工作?

代码

    ObjectMapper mapper = new ObjectMapper();       
    KeyHolder generatedKeyHolder = new GeneratedKeyHolder();

    jdbcOracle.update(new PreparedStatementCreator() { //Line 60: This line cited as containing NullPointerException error.

        @Override
        public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
            PreparedStatement ps = connection.prepareStatement("INSERT INTO MY_TABLE (MY_OBJ) VALUES (?)", new String[] {"ID"});
            try {
                ps.setString(1, mapper.writeValueAsString(myObj));
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return ps;
        }

    }, generatedKeyHolder);

    System.out.println("Generated Key: " + (String)generatedKeyHolder.getKeys().get("ID"));

尝试解决方案

  1. 我们已经创建了包含序列的备用表,而不是默认为SYS_GUID()。
  2. 我们尝试使用System.RETURN_GENERATED_KEY代替new String[] {"ID"}
  3. 我们确保所有计算机上的数据库权限都相同。
  4. 我们确认所有计算机上的数据库驱动程序都相同。
  5. 我可以删除, new String[] {"ID"}参数和, generatedKeyHolder参数以使prepareStatement运行,但由于我试图获取生成的密钥,这显然会使目的失败。
  6. 堆栈跟踪

    2016-05-04 00:05:43.148 ERROR 3156 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
    
    java.lang.NullPointerException: null
        at oracle.jdbc.driver.AutoKeyInfo.initMetaDataColumnIndexes(AutoKeyInfo.java:423) ~[ojdbc7-12.1.0.jar:12.1.0.1.0]
        at oracle.jdbc.driver.AutoKeyInfo.initMetaData(AutoKeyInfo.java:396) ~[ojdbc7-12.1.0.jar:12.1.0.1.0]
        at oracle.jdbc.driver.OracleReturnResultSet.getMetaData(OracleReturnResultSet.java:77) ~[ojdbc7-12.1.0.jar:12.1.0.1.0]
        at org.springframework.jdbc.core.ColumnMapRowMapper.mapRow(ColumnMapRowMapper.java:52) ~[spring-jdbc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.jdbc.core.ColumnMapRowMapper.mapRow(ColumnMapRowMapper.java:48) ~[spring-jdbc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:93) ~[spring-jdbc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate$3.doInPreparedStatement(JdbcTemplate.java:911) ~[spring-jdbc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate$3.doInPreparedStatement(JdbcTemplate.java:900) ~[spring-jdbc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:629) ~[spring-jdbc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:900) ~[spring-jdbc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at com.mysite.impl.MyImpl.save(MyImpl.java:60)
    

1 个答案:

答案 0 :(得分:9)

12.1.0.1有关于密钥生成的错误。使用Oracle JDBC驱动程序版本12.1.0.2。 链接:http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html