web-dev-qa-db-fra.com

java.sql.SQLException: nom de colonne non valide

Je n'arrive pas à comprendre pourquoi je reçois "Nom de colonne invalide" ici.

Nous avons essayé une variante du SQL directement dans Oracle, et cela fonctionne bien, mais lorsque je l’essaye avec jdbcTemplate, alors quelque chose ne va pas.

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();
                });

Le SQL complet qui fonctionne sur Oracle est le suivant:

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

Le stacktrace entier:

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
4
Shervin Asgari

Le problème n'est pas la requête. La requête fonctionne bien.

Le problème réside dans le mappage de lignes qui convertit une ligne de ResultSet en un objet de domaine. Il semble que dans le cadre du mappage de lignes dans votre application, vous essayez de lire dans la variable ResultSet une valeur d'une colonne qu'elle ne contient pas.

Les lignes principales de votre stacktrace sont les trois suivantes, près du bas:

    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)

Le milieu de ces trois lignes semble être dans votre code. La ligne 69 de votre classe Application contient un lambda qui appelle ResultSet.getString(), mais comme cela entraîne une erreur 'Nom de colonne invalide', vous passez (a) une chaîne pour un nom de colonne plutôt qu'un index de colonne numérique, et (b ) le nom de colonne que vous transmettez n’existe pas dans le jeu de résultats.

Maintenant que vous avez modifié votre question pour inclure l'appel à jdbcTemplate.query(), et en particulier le lambda chargé de mapper une ligne d'ensemble de résultats sur un objet, le problème est un peu plus clair. Lorsque vous appelez rs.getInt(...) ou rs.getString(...) avec des noms de colonnes plutôt que des index, n'incluez pas de préfixe tel que p. ou x.. Au lieu d'écrire rs.getInt("p.applicationid") ou rs.getInt("x.datadocumentid"), écrivez rs.getInt("applicationid") ou rs.getInt("datadocumentid").

11
Luke Woodward

Vous avez besoin de la définition de la table pour savoir où se situe le problème. Installez/exécutez Oracle SQL Developer (gratuit), configurez la connexion JDBC et étudiez le schéma.

Vous devez vérifier l'existence des colonnes suivantes:

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