Oracle CLOB字段映射为String时Tomcat 8.5偶发返回空字符串问题咨询
问题根本原因
- 应用服务器的JDBC层默认实现差异
你最初将Oracle CLOB字段映射为String类型时,依赖持久化框架(JPA/MyBatis等)自动完成JDBC返回的java.sql.Clob代理对象到String的转换。Glassfish 3.5内置了适配好的Oracle JDBC驱动和默认持久化实现,会强制在数据库连接有效阶段完成CLOB全量内容的读取和String转换,因此不会出现异常。
Tomcat 8.5本身不内置Oracle JDBC驱动,你部署时使用的独立引入的驱动版本、Tomcat连接池配置、持久化框架参数均和Glassfish存在差异,部分场景下CLOB还未完成内容读取,数据库连接就已经被释放回连接池,导致读取失败。数据量低于驱动预加载阈值的CLOB内容会被提前缓存到代理对象中,即使连接关闭也能正常返回,这就是你遇到的部分XML正常、部分返回空的现象。 - CLOB的惰性加载特性限制
Oracle CLOB类型在JDBC规范中默认是惰性加载的,Clob代理对象本身不存储实际内容,只有主动调用getCharacterStream()、getSubString()等方法时才会向数据库拉取实际数据。很多旧版本Oracle JDBC驱动遇到读取CLOB时连接已关闭的场景,不会抛出明确异常,而是直接返回空字符串,刚好匹配你遇到的问题表现。 - 修改为CLOB类型后恢复正常的逻辑
你将实体字段类型修改为java.sql.Clob后,持久化框架不会提前执行CLOB到String的自动转换,你调用getPayload()获取到CLOB代理对象后,内容读取操作是在数据库连接有效的业务上下文内执行的,因此所有XML数据都可以正常读取。
内容的提问来源于stack exchange,提问作者sineverba
相关产品推荐
相关产品推荐

