Logback DB Appender无法写入Oracle XE数据库问题求助
解决Logback无法写入Oracle XE数据库的问题
核心问题分析
Debug模式下的ORA-04043: object logging_event does not exists错误,本质是Logback使用的表名与Oracle中实际存在的表名不匹配,或者数据库连接/权限存在问题。Oracle对表名大小写的处理规则是关键:
- 未加双引号的表名会被自动转为大写存储
- Logback的
DBAppender默认使用小写表名生成SQL语句
分步解决方案
1. 确认Oracle中表的实际名称
先执行SQL查询,确认表的真实大小写:
SELECT table_name FROM user_tables WHERE lower(table_name) = 'logging_event';
如果返回的是LOGGING_EVENT(大写),说明你之前创建表时未加双引号,Oracle自动转成了大写。
2. 修改Logback配置适配表名
在DBAppender中显式指定Oracle中实际存在的大写表名,覆盖默认的小写表名配置:
<appender name="Database-Appender" class="ch.qos.logback.classic.db.DBAppender"> <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource"> <driverClass>oracle.jdbc.OracleDriver</driverClass> <url>jdbc:oracle:thin:@localhost:1521/XEPDB1</url> <user>my_user</user> <password>my_password</password> </connectionSource> <!-- 指定Oracle中实际的大写表名 --> <tableName>LOGGING_EVENT</tableName> <eventPropertyTableName>LOGGING_EVENT_PROPERTY</eventPropertyTableName> <eventExceptionTableName>LOGGING_EVENT_EXCEPTION</eventExceptionTableName> </appender>
3. 验证数据库用户权限
确保my_user拥有对日志表和序列的必要权限:
-- 授予表的插入、查询权限 GRANT INSERT, SELECT ON LOGGING_EVENT TO my_user; GRANT INSERT, SELECT ON LOGGING_EVENT_PROPERTY TO my_user; GRANT INSERT, SELECT ON LOGGING_EVENT_EXCEPTION TO my_user; -- 授予序列的访问权限 GRANT SELECT, ALTER ON logging_event_id_seq TO my_user;
4. 确认表创建在正确的PDB中
你连接的是Oracle XE的XEPDB1可插拔数据库,需确保表是创建在该PDB下,而非CDB根容器:
-- 切换到XEPDB1 ALTER SESSION SET CONTAINER = XEPDB1; -- 重新创建序列、表、触发器(如果之前建错了容器) CREATE SEQUENCE logging_event_id_seq MINVALUE 1 START WITH 1; -- 后续表和触发器创建语句同上
5. 测试数据库连接有效性
写一个简单的JDBC测试代码,验证连接和插入操作是否正常:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; public class OracleLogTest { public static void main(String[] args) throws Exception { Class.forName("oracle.jdbc.OracleDriver"); try (Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521/XEPDB1", "my_user", "my_password" )) { String sql = "INSERT INTO LOGGING_EVENT (timestmp, formatted_message, logger_name, level_string, caller_filename, caller_class, caller_method, caller_line) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; try (PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setLong(1, System.currentTimeMillis()); pstmt.setString(2, "Test log message"); pstmt.setString(3, "TestLogger"); pstmt.setString(4, "INFO"); pstmt.setString(5, "Test.java"); pstmt.setString(6, "TestClass"); pstmt.setString(7, "testMethod"); pstmt.setString(8, "123"); pstmt.executeUpdate(); System.out.println("Insert success"); } } } }
如果这段代码能成功插入数据,说明数据库连接和权限没问题,问题出在Logback配置;如果失败,排查数据库连接或权限问题。
内容的提问来源于stack exchange,提问作者user17982071
相关产品推荐
相关产品推荐

