web-dev-qa-db-ja.com

java.sql.SQLException:無効な列名

ここで"Invalid column name"になっている理由がわかりません。

Oracleで直接sqlのバリアントを試してみましたが、正常に動作しますが、jdbcTemplateを使用して試してみると、何かが間違っています。

List<Dataholder> alleXmler = jdbcTemplate.query("select p.applicationid, x.datadocumentid, x.datadocumentxml " +
                        "from CFUSERENGINE51.PROCESSENGINE p " +
                        "left join CFUSERENGINE51.DATADOCUMENTXML x " +
                        "on p.processengineguid = x.processengineguid " +
                        "where x.datadocumentid = 'Disbursment' " +
                        "and p.phasecacheid = 'Disbursed' ",
                (rs, rowNum) -> {
                    return Dataholder.builder()
                            .applicationid(rs.getInt("p.applicationid"))
                            .datadocumentId(rs.getInt("x.datadocumentid"))
                            .xml(lobHandler.getClobAsString(rs, "x.datadocumentxml"))
                            .build();
                });

Oracleで動作するsql全体は次のとおりです。

select
process.applicationid,
xml.datadocumentid,
xml.datadocumentxml
from CFUSERENGINE51.PROCESSENGINE process
left join CFUSERENGINE51.DATADOCUMENTXML xml
on process.processengineguid = xml. processengineguid
where xml.datadocumentid = 'Disbursment'
and process.phasecacheid = 'Disbursed'
and process.lastupdatetime > sysdate-14

スタックトレース全体:

Java.lang.reflect.InvocationTargetException
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:498)
    at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.Java:507)
    at Java.lang.Thread.run(Thread.Java:745)
Caused by: Java.lang.IllegalStateException: Failed to execute CommandLineRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.Java:803)
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.Java:784)
    at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.Java:771)
    at org.springframework.boot.SpringApplication.run(SpringApplication.Java:316)
    at org.springframework.boot.SpringApplication.run(SpringApplication.Java:1186)
    at org.springframework.boot.SpringApplication.run(SpringApplication.Java:1175)
    at no.gjensidige.bank.datavarehus.kontonrinfridd.Application.main(Application.Java:44)
    ... 6 more
Caused by: org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [select p.applicationid, x.datadocumentid, x.datadocumentxml from CFUSERENGINE51.PROCESSENGINE p left join CFUSERENGINE51.DATADOCUMENTXML x on p.processengineguid = x.processengineguid where x.datadocumentid = 'Disbursment' ]; nested exception is Java.sql.SQLException: Invalid column name
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.Java:231)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.Java:73)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.Java:419)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.Java:474)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.Java:484)
    at no.gjensidige.bank.datavarehus.kontonrinfridd.Application.run(Application.Java:61)
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.Java:800)
    ... 12 more
Caused by: Java.sql.SQLException: Invalid column name
    at Oracle.jdbc.driver.OracleStatement.getColumnIndex(OracleStatement.Java:4146)
    at Oracle.jdbc.driver.InsensitiveScrollableResultSet.findColumn(InsensitiveScrollableResultSet.Java:300)
    at Oracle.jdbc.driver.GeneratedResultSet.getString(GeneratedResultSet.Java:1460)
    at org.Apache.commons.dbcp2.DelegatingResultSet.getString(DelegatingResultSet.Java:267)
    at org.Apache.commons.dbcp2.DelegatingResultSet.getString(DelegatingResultSet.Java:267)
    at no.gjensidige.bank.datavarehus.kontonrinfridd.Application.lambda$run$0(Application.Java:69)
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.Java:93)
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.Java:60)
    at org.springframework.jdbc.core.JdbcTemplate$1QueryStatementCallback.doInStatement(JdbcTemplate.Java:463)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.Java:408)
    ... 16 more
8
Shervin Asgari

問題はクエリではありません。クエリは正常に実行されています。

問題は、行をResultSetからドメインオブジェクトに変換する行マッピングにあります。アプリケーションの行マッピングの一部として、ResultSetに含まれていない列の値を読み取ろうとしているようです。

スタックトレースの重要な行は、下の近くにある次の3つです。

_    at org.Apache.commons.dbcp2.DelegatingResultSet.getString(DelegatingResultSet.Java:267)
    at no.gjensidige.bank.datavarehus.kontonrinfridd.Application.lambda$run$0(Application.Java:69)
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.Java:93)
_

これらの3行の中央は、コード内にあるように見えます。 Applicationクラスの69行目にはResultSet.getString()を呼び出しているラムダが含まれていますが、これにより「列名が無効です」というエラーが発生するため、(a)列に文字列を渡しています数値の列インデックスではなく名前、および(b)渡す列名が結果セットに存在しません。

質問を編集してjdbcTemplate.query()の呼び出し、特に結果セットの行をオブジェクトにマッピングするラムダを含めるようになったので、問題は少し明確になりました。インデックスではなく列名でrs.getInt(...)またはrs.getString(...)を呼び出すときは、_p._や_x._などのプレフィックスを含めないでください。 rs.getInt("p.applicationid")またはrs.getInt("x.datadocumentid")を記述する代わりに、rs.getInt("applicationid")またはrs.getInt("datadocumentid")を記述します。

18
Luke Woodward

問題がどこにあるかを知るには、テーブル定義が必要です。インストール/実行 Oracle SQL Developer (無料)、JDBC接続のセットアップ、スキーマの調査。

次の列の存在を確認する必要があります。

CFUSERENGINE51.PROCESSENGINE.applicationid,
CFUSERENGINE51.PROCESSENGINE.lastupdatetime
CFUSERENGINE51.PROCESSENGINE.phasecacheid
CFUSERENGINE51.PROCESSENGINE.processengineguid
CFUSERENGINE51.DATADOCUMENTXML.datadocumentid
CFUSERENGINE51.DATADOCUMENTXML.datadocumentxml
CFUSERENGINE51.DATADOCUMENTXML.processengineguid
0
sax