jOOQ 内置方法生成具有完全限定的“列”名称的不确定查询

Posted

技术标签:

【中文标题】jOOQ 内置方法生成具有完全限定的“列”名称的不确定查询【英文标题】:jOOQ inbuilt method generates uncertain query which has fully qualified "column" name 【发布时间】:2021-11-01 00:22:29 【问题描述】:

我正在开发 Spring Boot 并连接到 PostgreSQL 并使用 jOOQ。

jOOQ 的 DSLContext 内置“更新”方法生成具有完全限定列名的不确定查询。在 PostgreSQL 上运行时会抛出 BadSqlGrammerException。

使用的内置方法

dslContext.update(Tables.TEST).set(row(Tables.TEST.COLUMN1, Tables.TEST.COLUMN2),
                row(col1, col2))
                .where(Tables.TEST.COLUMN3.eq(col3))
                .execute();

生成的查询

update "abc"."test" set "abc"."test"."column1" = ?, "abc"."test"."column2" = ? where "abc"."test"."column3" = ?;

发生异常

"message": "Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.jdbc.BadSqlGrammarException: jOOQ; bad SQL grammar [update \"abc\".\"test\" set \"abc\".\"test\".\"column1\" = ?, \"abc\".\"test\".\"column2\" = ? where \"abc\".\"test\".\"column3\" = ?]; nested exception is org.postgresql.util.PSQLException: ERROR: column \"abc\" of relation \"test\" does not exist\n Position: 30]",

堆栈跟踪

org.postgresql.util.PSQLException: ERROR: column \"abc\" of relation \"test\" does not exist
 Position: 30
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2553)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2285)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:323)
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:481)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:401)
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:164)
    at org.postgresql.jdbc.PgPreparedStatement.execute(PgPreparedStatement.java:153)
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
    at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.execute(HikariProxyPreparedStatement.java)
    at org.jooq.tools.jdbc.DefaultPreparedStatement.execute(DefaultPreparedStatement.java:214)
    at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:458)
    at org.jooq.impl.AbstractDMLQuery.execute(AbstractDMLQuery.java:953)
    at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:375)
    at org.jooq.impl.AbstractDelegatingQuery.execute(AbstractDelegatingQuery.java:119)
    at *package & class names* java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:764)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:887)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1684)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)

这种情况只发生过一次,我无法重现此问题

请帮助解决这个问题。

【问题讨论】:

【参考方案1】:

如果发生这种情况,则说明您使用的 SQLDialect 不正确。堆栈跟踪(您省略了)应该表明您的案例中使用了 SQLDialect

【讨论】:

用 Stack Trace 更新了问题 你的意思是在应用程序属性文件中包含“spring.jooq.sql-dialect = Postgres”并且这个问题不会重复吗? @BrajeshJha:好吧,看起来堆栈跟踪不是来自 jOOQ 的 DataAccessException 的那个,它包含 SQLDialect。无论如何,您可以轻松检查。只需登录 dslContext.dialect() 即可查看您配置 jOOQ 的方言。我无法告诉您为什么配置错误,可能有多种原因,但这就是这里发生的情况。 Postgres 是配置的方言。我已经在更新方法生成不确定查询的地方准确记录了这一点: logger.info("SQLDialect Used --> ",dslContext.dialect()); "message":"使用的 SQLDialect --> POSTGRES" @BrajeshJha:但是,也许你没有显示你正在执行的 exact 代码?

以上是关于jOOQ 内置方法生成具有完全限定的“列”名称的不确定查询的主要内容,如果未能解决你的问题,请参考以下文章

具有完全相同名称空间的不明确引用

BigTable:来自不同列族的两个列限定符可以具有相同的名称吗?

如何使用实体 bean 类名和属性名生成类和属性?

带有限定标识符的 where 子句中的不明确列

PHP使用命名空间:别名/导入(Aliasing/Importing)

如果只有完全限定名称,如何获取 java 类的二进制名称?