使用 jOOQ 执行 PL/SQL 函数时的 Java 空指针
Posted
技术标签:
【中文标题】使用 jOOQ 执行 PL/SQL 函数时的 Java 空指针【英文标题】:Java null pointer when executing a PL/SQL function using jOOQ 【发布时间】:2018-12-11 22:47:33 【问题描述】:我目前正在尝试调用一个接受多个输入/输出参数的 PL/SQL 函数。该函数包含以下数据类型:
字符串。 字符串数组。但是,当应用程序设置数据以将其发送到数据库服务器时,应用程序会抛出 空指针异常,该异常与引起的实际错误无关(请注意,实际错误是如下所示,因为这是在调试应用程序时计算出来的)。
应用程序正在准备以下数据:
-
字符串 -> 这些没有问题
列表 -> 转换为 CustTabVarchar2_50Record
列表 -> 转换为 CustTabVarchar2_4000Record
然后将其传递给 jOOQ 生成的类,该类包含 PL/SQL 函数的 Java 包装器。
此时它在迭代参数时失败,特别是在迭代 CustTabVarchar2_50Record 时失败。
此时会抛出异常:
java.lang.NoSuchMethodException: No similar method createARRAY with params [class java.lang.String, class [Ljava.lang.Object;] could be found on type class org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8.
我目前假设它可能是以下问题之一:
-
jOOQ 的一个问题。
jBoss 使用的库不正确,因为它声明:'org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8'
PL SQL 标头:
procedure a_l_ws(
p_i_num in varchar2,
p_s in varchar2,
p_u in varchar2,
p_tpu in varchar2,
p_tpa in varchar2,
p_data_desc in cust_tab_varchar2_50,
p_l in cust_tab_varchar2_4000,
p_r out pls_integer,
p_p out varchar2,
p_appl out varchar2,
p_ml out cust_tab_varchar2_12,
p_m out cust_tab_varchar2_4000)
堆栈跟踪:
result = ReflectException@23035 Method threw 'org.jooq.tools.reflect.ReflectException' exception.
detailMessage = "java.lang.NoSuchMethodException: No similar method createARRAY with params [class java.lang.String, class [Ljava.lang.Object;] could be found on type class org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8."
cause = NoSuchMethodException@23038 "java.lang.NoSuchMethodException: No similar method createARRAY with params [class java.lang.String, class [Ljava.lang.Object;] could be found on type class org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8."
detailMessage = "No similar method createARRAY with params [class java.lang.String, class [Ljava.lang.Object;] could be found on type class org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8."
cause = NoSuchMethodException@23038 "java.lang.NoSuchMethodException: No similar method createARRAY with params [class java.lang.String, class [Ljava.lang.Object;] could be found on type class org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8."
stackTrace = StackTraceElement[102]@23047
0 = StackTraceElement@23049 "org.jooq.tools.reflect.Reflect.similarMethod(Reflect.java:436)"… Navigate
1 = StackTraceElement@23050 "org.jooq.tools.reflect.Reflect.call(Reflect.java:366)"… Navigate
2 = StackTraceElement@23051 "org.jooq.impl.DefaultBinding.createOracleARRAY(DefaultBinding.java:1403)"… Navigate
3 = StackTraceElement@23052 "org.jooq.impl.DefaultBinding.set(DefaultBinding.java:1243)"… Navigate
4 = StackTraceElement@23053 "org.jooq.impl.DefaultBindContext.bindValue0(DefaultBindContext.java:62)"… Navigate
5 = StackTraceElement@23054 "org.jooq.impl.AbstractBindContext.bindValue(AbstractBindContext.java:127)"… Navigate
6 = StackTraceElement@23055 "org.jooq.impl.ArrayConstant.bind0(ArrayConstant.java:110)"… Navigate
7 = StackTraceElement@23056 "org.jooq.impl.ArrayConstant.accept(ArrayConstant.java:81)"… Navigate
8 = StackTraceElement@23057 "org.jooq.impl.AbstractBindContext.bindInternal(AbstractBindContext.java:257)"… Navigate
9 = StackTraceElement@23058 "org.jooq.impl.AbstractBindContext.visit0(AbstractBindContext.java:91)"… Navigate
10 = StackTraceElement@23059 "org.jooq.impl.AbstractContext.visit0(AbstractContext.java:402)"… Navigate
11 = StackTraceElement@23060 "org.jooq.impl.AbstractContext.visit(AbstractContext.java:168)"… Navigate
12 = StackTraceElement@23061 "org.jooq.impl.AbstractRoutine.bind1(AbstractRoutine.java:588)"… Navigate
13 = StackTraceElement@23062 "org.jooq.impl.AbstractRoutine.bind0(AbstractRoutine.java:558)"… Navigate
14 = StackTraceElement@23063 "org.jooq.impl.AbstractRoutine.accept(AbstractRoutine.java:508)"… Navigate
15 = StackTraceElement@23064 "org.jooq.impl.AbstractBindContext.bindInternal(AbstractBindContext.java:257)"… Navigate
16 = StackTraceElement@23065 "org.jooq.impl.AbstractBindContext.visit0(AbstractBindContext.java:91)"… Navigate
17 = StackTraceElement@23066 "org.jooq.impl.AbstractContext.visit0(AbstractContext.java:402)"… Navigate
18 = StackTraceElement@23067 "org.jooq.impl.AbstractContext.visit(AbstractContext.java:168)"… Navigate
19 = StackTraceElement@23068 "org.jooq.impl.AbstractRoutine.executeCallableStatement(AbstractRoutine.java:439)"… Navigate
20 = StackTraceElement@23069 "org.jooq.impl.AbstractRoutine.execute(AbstractRoutine.java:310)"… Navigate
21 = StackTraceElement@23070 "org.jooq.impl.AbstractRoutine.execute(AbstractRoutine.java:287)"… Navigate
22 = StackTraceElement@23071 "c.r.w.jooq.model.db.db.packages.Aim.aimLoadWs(Aim.java:71)"… Navigate
23 = StackTraceElement@23072 "c.r.w.jsonapi.repositories.onboarding.OnboardingService.loadApplication(OnboardingService.java:378)"… Navigate
24 = StackTraceElement@23073 "c.r.w.jsonapi.repositories.onboarding.OnboardingService.loadMerchant(OnboardingService.java:74)"… Navigate
25 = StackTraceElement@23074 "c.r.w.jsonapi.repositories.merchants.merchant.resource.MerchantRepository.saveRecord(MerchantRepository.java:93)"… Navigate
26 = StackTraceElement@23075 "c.r.w.jsonapi.repositories.merchants.merchant.resource.MerchantRepository.saveRecord(MerchantRepository.java:24)"… Navigate
27 = StackTraceElement@23076 "c.r.w.jsonapi.repositories.AbstractResourceRepository.save(AbstractResourceRepository.java:204)"… Navigate
28 = StackTraceElement@23077 "c.r.w.jsonapi.repositories.AbstractResourceRepository.save(AbstractResourceRepository.java:33)"… Navigate
29 = StackTraceElement@23078 "io.katharsis.core.internal.repository.adapter.ResourceRepositoryAdapter$4.invoke(ResourceRepositoryAdapter.java:133)"… Navigate
30 = StackTraceElement@23079 "io.katharsis.core.internal.repository.adapter.ResponseRepositoryAdapter$RepositoryRequestFilterChainImpl.doFilter(ResponseRepositoryAdapter.java:203)"… Navigate
31 = StackTraceElement@23080 "io.katharsis.core.internal.repository.adapter.ResourceRepositoryAdapter.save(ResourceRepositoryAdapter.java:145)"… Navigate
32 = StackTraceElement@23081 "io.katharsis.core.internal.repository.adapter.ResourceRepositoryAdapter.update(ResourceRepositoryAdapter.java:110)"… Navigate
33 = StackTraceElement@23082 "io.katharsis.core.internal.dispatcher.controller.ResourcePatch.handle(ResourcePatch.java:133)"… Navigate
34 = StackTraceElement@23083 "io.katharsis.core.internal.dispatcher.RequestDispatcher$DefaultFilterChain.doFilter(RequestDispatcher.java:126)"… Navigate
35 = StackTraceElement@23084 "io.katharsis.core.internal.dispatcher.RequestDispatcher.dispatchRequest(RequestDispatcher.java:80)"… Navigate
36 = StackTraceElement@23085 "io.katharsis.rs.KatharsisFilter.dispatchRequest(KatharsisFilter.java:151)"… Navigate
37 = StackTraceElement@23086 "io.katharsis.rs.KatharsisFilter.filter(KatharsisFilter.java:111)"… Navigate
38 = StackTraceElement@23087 "org.apache.cxf.jaxrs.utils.JAXRSUtils.runContainerRequestFilters(JAXRSUtils.java:1642)"… Navigate
39 = StackTraceElement@23088 "org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:106)"… Navigate
40 = StackTraceElement@23089 "org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:77)"… Navigate
41 = StackTraceElement@23090 "org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)"… Navigate
42 = StackTraceElement@23091 "org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)"… Navigate
43 = StackTraceElement@23092 "org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:251)"… Navigate
44 = StackTraceElement@23093 "org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)"… Navigate
45 = StackTraceElement@23094 "org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)"… Navigate
46 = StackTraceElement@23095 "org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)"… Navigate
47 = StackTraceElement@23096 "org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180)"… Navigate
48 = StackTraceElement@23097 "org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:293)"… Navigate
49 = StackTraceElement@23098 "org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:270)"… Navigate
50 = StackTraceElement@23099 "io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)"… Navigate
51 = StackTraceElement@23100 "io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)"… Navigate
52 = StackTraceElement@23101 "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)"… Navigate
53 = StackTraceElement@23102 "org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)"… Navigate
54 = StackTraceElement@23103 "org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)"… Navigate
55 = StackTraceElement@23104 "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)"… Navigate
56 = StackTraceElement@23105 "org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)"… Navigate
57 = StackTraceElement@23106 "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)"… Navigate
58 = StackTraceElement@23107 "org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)"… Navigate
59 = StackTraceElement@23108 "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)"… Navigate
60 = StackTraceElement@23109 "org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)"… Navigate
61 = StackTraceElement@23110 "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)"… Navigate
62 = StackTraceElement@23111 "c.r.wsecurity.oauth2.AuthenticationFilterOAuth2.doFilter(AuthenticationFilterOAuth2.java:73)"… Navigate
63 = StackTraceElement@23112 "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)"… Navigate
64 = StackTraceElement@23113 "org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)"… Navigate
65 = StackTraceElement@23114 "org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)"… Navigate
66 = StackTraceElement@23115 "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)"… Navigate
67 = StackTraceElement@23116 "org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)"… Navigate
68 = StackTraceElement@23117 "org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)"… Navigate
69 = StackTraceElement@23118 "org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)"… Navigate
70 = StackTraceElement@23119 "org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)"… Navigate
71 = StackTraceElement@23120 "org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)"… Navigate
72 = StackTraceElement@23121 "org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)"… Navigate
73 = StackTraceElement@23122 "io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)"… Navigate
74 = StackTraceElement@23123 "io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)"… Navigate
75 = StackTraceElement@23124 "io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)"… Navigate
76 = StackTraceElement@23125 "io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)"… Navigate
77 = StackTraceElement@23126 "io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)"… Navigate
78 = StackTraceElement@23127 "org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)"… Navigate
79 = StackTraceElement@23128 "io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)"… Navigate
80 = StackTraceElement@23129 "io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)"… Navigate
81 = StackTraceElement@23130 "io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)"… Navigate
82 = StackTraceElement@23131 "io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)"… Navigate
83 = StackTraceElement@23132 "io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)"… Navigate
84 = StackTraceElement@23133 "io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)"… Navigate
85 = StackTraceElement@23134 "io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)"… Navigate
86 = StackTraceElement@23135 "io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)"… Navigate
87 = StackTraceElement@23136 "io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)"… Navigate
88 = StackTraceElement@23137 "io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)"… Navigate
89 = StackTraceElement@23138 "io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)"… Navigate
90 = StackTraceElement@23139 "org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)"… Navigate
91 = StackTraceElement@23140 "io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)"… Navigate
92 = StackTraceElement@23141 "io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)"… Navigate
93 = StackTraceElement@23142 "io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:285)"… Navigate
94 = StackTraceElement@23143 "io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:264)"… Navigate
95 = StackTraceElement@23144 "io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)"… Navigate
96 = StackTraceElement@23145 "io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:175)"… Navigate
97 = StackTraceElement@23146 "io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)"… Navigate
98 = StackTraceElement@23147 "io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:792)"… Navigate
99 = StackTraceElement@23148 "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)"… Navigate
… (2 more items. Double-click to see)
suppressedExceptions = Collections$UnmodifiableRandomAccessList@22457 size = 0
stackTrace = StackTraceElement[101]@23039
suppressedExceptions = Collections$UnmodifiableRandomAccessList@22457 size = 0
【问题讨论】:
您尝试使用 createArrayOf 而不是 createARRAY 的方法不正确吗?我正在查看repository.jboss.org/nexus/content/unzip/unzip/org/jboss/… 中的文档,其中提到了具有相同签名但名称不同的类似方法。 如何创建在c.r.w.jooq.model.db.db.packages.Aim.aimLoadWs
中使用的jOOQ Configuration
/ DSLContext
?我对您提供给 jOOQ 的 ConnectionProvider
和/或 DataSource
特别感兴趣。
另外,您使用的是什么 jOOQ 版本?调用WrappedConnectionJDK8.getUnderlyingConnection()
时是否得到OracleConnection
的实例?同时,我为此创建了一个问题:github.com/jOOQ/jOOQ/issues/7641
@LukasEder 从 jboss 配置中检索数据源。这意味着这是在 jBoss 中的standalone.xml 中预定义的,并由“jBoss EAP 7.0”创建。本例中使用的方言是“Oracle 11g”,jOOQ 版本是“3.9.4”。请注意,这曾经在 Java 7 中工作,但是随着 Java 8 的变化,情况发生了变化。
@Joseph118:您在调用 WrappedConnectionJDK8.getUnderlyingConnection() 时是否获得了 OracleConnection 的实例?这将有助于修复它。
【参考方案1】:
这似乎与https://github.com/jOOQ/jOOQ/issues/3639 相关,当使用配置了 Oracle JDBC 驱动程序的连接包装器(通过数据源或连接池)时。在您的情况下,您似乎正在使用 JBoss 数据源。如问题中所述,由于 createARRAY 不是标准 JDBC 而是特定于 Oracle,如果您使用 Oracle 方言创建 DSL 连接,jOOQ 将假定正在使用 Oracle 连接,因此尝试调用 Oracle 的 createARRAY() 而不是 createArrayOf( )。
也许 jOOQ 的作者可以阐明是否可以通过配置设置、修复或其他方式避免这种情况。
注意:必须将此作为答案而不是评论,因为我的声誉仍然很低。如果此条目获得高票,将在此处提供最终答案。
【讨论】:
ojdbc doesn't implementcreateArrayOf()
。另见:docs.oracle.com/en/database/oracle/oracle-database/12.2/jjdbc/…
没错。从提供的堆栈跟踪来看,jOOQ 似乎试图在只包含 createArrayOf() 的 org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8 上调用 createARRAY()。 repository.jboss.org/nexus/content/unzip/unzip/org/jboss/…
当然,但它在尝试解开OracleConnection
之后这样做,显然WrappedConnectionJDK8
不支持。所以,你的分析很可能是正确的。当 Spring JDBC Connection
包装器也没有打开 OracleConnection
时,您链接的 #3639 问题非常相似。这可能是一个错误,因此请随时将github.com/jOOQ/jOOQ/issues/7641 添加到您的答案中。【参考方案2】:
这似乎是 JBoss WrappedConnectionJDK8
的一个限制,它在调用时似乎没有正确解开 OracleConnection
类型:
OracleConnection ocn = wrapped.unwrap(OracleConnection.class);
过去,(as GilbertD has mentioned),jOOQ 通过反射调用供应商特定的展开方法来解决这些限制,例如那些在春天通过#3639。 WrappedConnectionJDK8.getUnderlyingConnection()
也可以这样做,请参阅 #7641
解决方法
作为一种解决方法,您可以从 JBoss 提供的 JDBC Connection
包装器中手动解包 OracleConnection
,并将其直接提供给 jOOQ,例如通过代理 JBoss DataSource
class WorkaroundDataSource implements DataSource
final DataSource delegate;
public WorkaroundDataSource(DataSource delegate)
this.delegate = delegate;
@Override
public Connection getConnection() throws SQLException
return unwrapOracleConnection(delegate.getConnection());
// ...
然后:
DSLContext ctx = DSL.using(new WorkaroundDataSource(jbossDataSource), SQLDialect.ORACLE);
【讨论】:
以上是关于使用 jOOQ 执行 PL/SQL 函数时的 Java 空指针的主要内容,如果未能解决你的问题,请参考以下文章