尝试通过Spring JDBC模板执行数据库代码时,我得到一个奇怪的ORA-00942: table or view does not exist
异常:
2019-12-26 22:01:36.863[0;39m [31mERROR[0;39m [35m12232[0;39m [2m---[0;39m [2m[ctor-http-nio-3][0;39m [36ma.w.r.e.AbstractErrorWebExceptionHandler[0;39m [2m:[0;39m [ca8305eb] 500 Server Error for HTTP GET "/exs/acs/accounts-links?limit=20&q=632626&showActive=false&systemName=IMMS"
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [select a.FACCIN, a.FACCKEY, a.FACCSNAME, b.LNKSYSTEM, b.LNKLOANKEY, a.FACCSTATUS, a.FACCCOND from BNYMACS.ACCOUNT a left outer join BNYMACS.LINKS b on a.FACCIN = b.lnkacc where (upper(a.FACCKEY) like ? or upper(FACCSNAME) like ? or (b.LNKLOANKEY like ? )) and b.LNKSYSTEM =? and rownum<=? order by 3 ]; nested exception is java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:235) ~[spring-jdbc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ? org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
|_ checkpoint ? HTTP GET "/exs/acs/accounts-links?limit=20&q=632626&showActive=false&systemName=IMMS" [ExceptionHandlingWebHandler]
Stack trace:
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:235) ~[spring-jdbc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
。 。 。 。 。 。 。
Caused by: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:509) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:461) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1104) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:550) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:268) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:655) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:270) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:91) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:807) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:983) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1168) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3666) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.T4CPreparedStatement.executeInternal(T4CPreparedStatement.java:1426) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3713) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1167) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
at com.p6spy.engine.wrapper.PreparedStatementWrapper.executeQuery(PreparedStatementWrapper.java:78) ~[p6spy-3.8.2.jar:na]
at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:678) ~[spring-jdbc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617) ~[spring-jdbc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:669) ~[spring-jdbc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:700) ~[spring-jdbc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712) ~[spring-jdbc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:763) ~[spring-jdbc-5.2.0.RELEASE.jar:5.2.0.RELEASE]
由于使用了Oracle驱动程序,由于开发人员已关闭oracle.jdbc.driver.OraclePreparedStatementWrapper
源代码,因此我无法真正调试ojdbc8
中的情况。
奇怪的是,在调试会话期间使用其参数提取并复制到外部SQL客户端时,来自Spring JDBC模板的查询进入Oracle驱动程序,在那儿可以正常工作:
select a.FACCIN, a.FACCKEY, a.FACCSNAME, b.LNKSYSTEM, b.LNKLOANKEY, a.FACCSTATUS, a.FACCCOND from BNYMACS.ACCOUNT a left outer join BNYMACS.LINKS b on a.FACCIN = b.lnkacc where (upper(a.FACCKEY) like '632626%' or upper(FACCSNAME) like '632626%' or (b.LNKLOANKEY like '632626%' )) and b.LNKSYSTEM ='IMMS' and rownum<=20 order by 3 ;
并产生结果的多条记录。
这是有问题的Spring存储库:
import static cwp.services.adhoc_processor.domain.acs.Account.*;
import static cwp.services.adhoc_processor.domain.acs.Links.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import cwp.services.adhoc_processor.domain.acs.AccountLinkDetail;
import cwp.services.adhoc_processor.domain.acs.AccountLinkDetail.AccountLinkDetailBuilder;
import cwp.services.adhoc_processor.domain.acs.AccountLinksList;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class AccountLinksRepositoryCustomImpl implements AccountLinksRepositoryCustom {
private static final String TERMINATED = "TERMINATED";
private static final String STOPPED = "STOPPED";
private final static String STATIC_QUERY_PART = "select a.FACCIN, a.FACCKEY, a.FACCSNAME, b.LNKSYSTEM, b.LNKLOANKEY, a.FACCSTATUS, a.FACCCOND "
+ "from BNYMACS.ACCOUNT a left outer join BNYMACS.LINKS b "
+ "on a.FACCIN = b.lnkacc where (upper(a.FACCKEY) like ? or upper(FACCSNAME) like ? "
+ "or (b.LNKLOANKEY like ? )) and b.LNKSYSTEM =? ";
private final static String activeSuffix = "and upper(a.FACCSTATUS) <> 'TERMINATED' and upper(a.FACCCOND) <> 'STOPPED' ";
private final static String orderbyClause = " and rownum<=? order by 3 ";
@Autowired
@Qualifier("acsJdbcTemplate")
private JdbcTemplate template;
@Autowired
public void setDataSource(DataSource dataSource) {
this.template = new JdbcTemplate(dataSource);
}
@Override
public AccountLinksList searchByAccountOrLinks(String searchTerm, int limit, boolean isActive, String systemName) {
AccountLinksList accountLinksList = new AccountLinksList();
try {
String dynQuery = STATIC_QUERY_PART;
if (isActive)
dynQuery += activeSuffix;
dynQuery += orderbyClause;
List<AccountLinkDetail> accountDetailsList = template.<AccountLinkDetail>query(
dynQuery,
new Object[] { searchTerm, searchTerm, searchTerm, systemName, limit },
new RowMapper<AccountLinkDetail>() {
@Override
public AccountLinkDetail mapRow(ResultSet rs, int currentRow) throws SQLException {
AccountLinkDetailBuilder accountDetails = AccountLinkDetail.builder();
accountDetails
.accountId(rs.getLong(ID_COLUMN_NAME))
.accountKey(rs.getString(ACCOUNT_KEY_COLUMN_NAME))
.accountName(rs.getString(ACCOUNT_SHORT_NAME_COLUMN_NAME))
.loanKey(rs.getString(LOAN_KEY_COLUMN_NAME))
.systemName(rs.getString(LINK_SYSTEM_COLUMN_NAME));
if (rs.getString(CONDITION_COLUMN_NAME) != null
&& !rs.getString(CONDITION_COLUMN_NAME).equalsIgnoreCase(STOPPED)
&& rs.getString(STATUS_COLUMN_NAME) != null
&& !rs.getString(STATUS_COLUMN_NAME).equalsIgnoreCase(TERMINATED)) {
accountDetails.isActive(true);
}
return accountDetails.build();
}
});
accountLinksList.setAccountLinkDetail(accountDetailsList);
} catch (Exception e) {
log.error("Technical Exception", e);
throw e;
}
return accountLinksList;
}
}
这是数据库的配置方式:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = {"cwp.services.adhoc_processor.repository.acs" },
entityManagerFactoryRef = "acsEntityManagerFactory",
transactionManagerRef = "acsTransactionManager")
public class AcsDatasourceConfiguration {
@Autowired
private AcsDbProperties properties;
@Validated
@Component
@ConfigurationProperties(prefix = "acs.read.datasource")
public class AcsDbProperties extends HikariDBProperties {
}
@ConditionalOnBean(value = AcsDbProperties.class)
@Bean(name = "acsDataSource", destroyMethod = "")
public DataSource acsDataSource() {
return new HikariDataSource(new HikariConfig(properties.getProperties()));
}
@Bean("acsJdbcTemplate")
public JdbcTemplate pmtTemplate () throws Exception {
return new JdbcTemplate(acsDataSource());
}
@Bean(name = "acsEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean acsEntityManagerFactory(EntityManagerFactoryBuilder builder) {
return builder.dataSource(acsDataSource())
.packages("cwp.services.adhoc_processor.domain.acs" )
.persistenceUnit("acs")
.build();
}
/*
* Leaky requirement for the unsatisfied transaction manager bean stemming from nxn-workflow-services#NWFProcessEngineConfiguration.java dependency.
*
* N.B. MUST BE CALLED THIS EXACT NAME, else will get
* org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.PlatformTransactionManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=transactionManager)}
*
*/
@Bean("transactionManager") // <-- must be called `transactionManager`.
public PlatformTransactionManager acsTransactionManager
(
@Qualifier("acsEntityManagerFactory")
final LocalContainerEntityManagerFactoryBean acsEntityManagerFactory
) {
return new JpaTransactionManager(acsEntityManagerFactory.getObject());
}
}
这是用例的调用:
curl --location --request GET 'http://localhost:7010/exs/acs/accounts-links?limit=20&q=632626&showActive=false&systemName=IMMS' \
--header 'Content-Type: application/json'
该表似乎是同义词:
并且运行时用户为WEBSVC_READ:
直接查询数据库时,我使用的是相同的WEBSVC_READ模式,并且可以正常工作:
N.B。:该行为似乎仅与JDBC模板有关。以下JPA查询运行良好:
"select a from Account a, Links l where l.accountId = a.id and l.loanKey = :loanKey and l.linkSystem = :systemName and(upper(a.status) <> 'TERMINATED' or upper(a.condition) <>'STOPPED' )";
application.properties中包含以下内容:
spring.jpa.properties.hibernate.default_schema=BNYMACS
和这样配置的实体(无显式模式):
@Entity(name="Account")
@Table(name="ACCOUNT")
public class Account implements Serializable{...}
@Entity
@Table(name="LINKS")
@Data
public class Links implements Serializable{...}
这里可能有什么问题?这ORA-00942
是有意义的错误,还是只是其他内容的占位符?也许有人可以给我一些有用的指导,以帮助您深入了解本教程。
提前感谢。
罪魁祸首是我的存储库中以下错误和不必要的定义:
@Autowired
public void setDataSource(DataSource dataSource) {
this.template = new JdbcTemplate(dataSource);
}
它已经在Configuration类中定义,并且重新定义引起了所有破坏。