Can';t通过JMS客户端将大型文本消息排队到Oracle AQ上-ORA-00942:表或视图不存在

Can';t通过JMS客户端将大型文本消息排队到Oracle AQ上-ORA-00942:表或视图不存在,oracle,jdbc,jms,clob,oracle-aq,Oracle,Jdbc,Jms,Clob,Oracle Aq,我正在通过JMS客户端将JSON消息排队到JVM上的Oracle AQ上。这对于小的文本消息来说效果很好,但是对于大的消息来说却失败了。我认为这与Oracle使用VARCHAR处理较小的消息和切换到CLOB处理超过4000个字符的消息有关 AQ数据库脚本是 开始 DBMS_AQADM.CREATE_QUEUE_表( queue_table=>“MY.AQT_MY_收件箱”, 队列\有效负载\类型=>'SYS.AQ$\ JMS\文本\消息', comment=>'QueueTable for MY

我正在通过JMS客户端将JSON消息排队到JVM上的Oracle AQ上。这对于小的文本消息来说效果很好,但是对于大的消息来说却失败了。我认为这与Oracle使用
VARCHAR
处理较小的消息和切换到
CLOB
处理超过4000个字符的消息有关

AQ数据库脚本是

开始
DBMS_AQADM.CREATE_QUEUE_表(
queue_table=>“MY.AQT_MY_收件箱”,
队列\有效负载\类型=>'SYS.AQ$\ JMS\文本\消息',
comment=>'QueueTable for MY Inbox Messages',
多个_消费者=>FALSE,
排序列表=>“优先级,enq\U时间”
);
DBMS_AQADM.CREATE_队列(
queue_name=>“MY.AQ_MY_收件箱”,
comment=>“我的收件箱邮件队列”,
queue_table=>“MY.AQT_MY_收件箱”,
队列类型=>SYS.DBMS\u AQADM.NORMAL\u队列,
最大重试次数=>2880次,
重试\u延迟=>30
);
DBMS_AQADM.GRANT_QUEUE_特权(
特权=>“排队”,
queue_name=>“MY.AQ_MY_收件箱”,
被授权人=>“我的用户”
);
DBMS_AQADM.START_队列(
queue_name=>“MY.AQ_我的收件箱”
);
结束;
/
oracle依赖项通过Maven配置为


com.oracle.jdbc
ojdbc8
18.3.0.0
com.oracle
aqapi_g
11.2.0.4
异常堆栈跟踪为

Caused by: oracle.jms.AQjmsException: ORA-00942: table or view does not exist
    at oracle.jms.AQjmsUtil.writeClob(AQjmsUtil.java:640)
    at oracle.jms.AQjmsTextMessage.writeLob(AQjmsTextMessage.java:294)
    at oracle.jms.AQjmsProducer.jdbcEnqueue(AQjmsProducer.java:1054)
    at oracle.jms.AQjmsProducer.send(AQjmsProducer.java:747)
    at oracle.jms.AQjmsProducer.send(AQjmsProducer.java:517)
    at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:634)
    at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:608)
    at org.springframework.jms.core.JmsTemplate.lambda$send$3(JmsTemplate.java:586)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:504)
    ... 20 common frames omitted
Caused by: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
    at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:494)
    at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:446)
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1052)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:537)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:255)
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:610)
    at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:249)
    at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:82)
    at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:924)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1136)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3640)
    at oracle.jdbc.driver.T4CCallableStatement.executeInternal(T4CCallableStatement.java:1318)
    at oracle.jdbc.driver.OraclePreparedStatement.executeLargeUpdate(OraclePreparedStatement.java:3730)
    at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3710)
    at oracle.jdbc.driver.OracleCallableStatement.executeUpdate(OracleCallableStatement.java:4265)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1061)
    at oracle.jms.AQjmsUtil.writeClob(AQjmsUtil.java:605)
    ... 28 common frames omitted
Caused by: oracle.jdbc.OracleDatabaseException: ORA-00942: table or view does not exist
    at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:498)
    ... 44 common frames omitted

我能够在
AQjmsUtil.writeClob
中放置一个断点,并且我可以看到下面的异常被抛出

clobStmt=(OracleCallableStatement)db\u conn.prepareCall(“更新”+queueTable+“选项卡集tab.user\u data.text\u lob=?其中tab.msgid=?”;
clobStmt.setString(1,textData);
立位体(2,msgid);
int count=clobStmt.executeUpdate();
CLOB
逻辑正在执行
UPDATE
操作,而对于使用
VARCHAR
的较小字符串,我相信它只执行
插入操作。违规的
UPDATE
语句被删除

更新MY.AQT\u我的收件箱选项卡set tab.user\u data.text\u lob=?其中tab.msgid=?
通过执行以下
GRANT
脚本解决了该问题

将MY.AQT_MY_收件箱上的更新授予MY_用户;
这个解决方案的奇怪之处在于,我不需要此表的
INSERT
授权(只有上覆队列的
ENQUEUE
授权)。我觉得这是oracle实现中的一个小错误,
INSERT
UPDATE
授权都应该由
ENQUEUE
授权添加。或者JMS API应该为
CLOB
执行一次
INSERT
,而不是
UPDATE
(类似于
VARCHAR
的实现方式)