Selaa lähdekoodia

fix: 添加 PostgreSQL JSONB 类型处理器

- 创建 PostgreSqlJsonbTypeHandler 处理 PostgreSQL JSONB 类型
- 使用 PGobject 正确设置 JSONB 类型参数
- 更新 ParseTask 实体使用新的类型处理器
- common 模块添加 PostgreSQL 依赖(provided scope)
何文松 1 kuukausi sitten
vanhempi
commit
839cb73680

+ 7 - 0
backend/common/pom.xml

@@ -52,6 +52,13 @@
             <artifactId>mybatis-plus-boot-starter</artifactId>
         </dependency>
         
+        <!-- PostgreSQL Driver (for JSONB type handler) -->
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        
         <!-- JWT -->
         <dependency>
             <groupId>io.jsonwebtoken</groupId>

+ 68 - 0
backend/common/src/main/java/com/lingyue/common/mybatis/PostgreSqlJsonbTypeHandler.java

@@ -0,0 +1,68 @@
+package com.lingyue.common.mybatis;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+import org.postgresql.util.PGobject;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * PostgreSQL JSONB 类型处理器
+ * 
+ * 用于处理 PostgreSQL 的 JSONB 类型字段与 Java 对象之间的转换。
+ * 解决 MyBatis-Plus JacksonTypeHandler 无法正确处理 PostgreSQL JSONB 类型的问题。
+ * 
+ * @author lingyue
+ * @since 2026-01-17
+ */
+@MappedTypes({Object.class})
+@MappedJdbcTypes(JdbcType.OTHER)
+public class PostgreSqlJsonbTypeHandler extends BaseTypeHandler<Object> {
+    
+    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+    
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
+        PGobject pgObject = new PGobject();
+        pgObject.setType("jsonb");
+        try {
+            pgObject.setValue(OBJECT_MAPPER.writeValueAsString(parameter));
+        } catch (JsonProcessingException e) {
+            throw new SQLException("Error converting object to JSONB: " + e.getMessage(), e);
+        }
+        ps.setObject(i, pgObject);
+    }
+    
+    @Override
+    public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        return parseJson(rs.getString(columnName));
+    }
+    
+    @Override
+    public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        return parseJson(rs.getString(columnIndex));
+    }
+    
+    @Override
+    public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        return parseJson(cs.getString(columnIndex));
+    }
+    
+    private Object parseJson(String json) throws SQLException {
+        if (json == null || json.isEmpty()) {
+            return null;
+        }
+        try {
+            return OBJECT_MAPPER.readValue(json, Object.class);
+        } catch (JsonProcessingException e) {
+            throw new SQLException("Error parsing JSONB: " + e.getMessage(), e);
+        }
+    }
+}

+ 1 - 1
backend/parse-service/src/main/java/com/lingyue/parse/entity/ParseTask.java

@@ -39,7 +39,7 @@ public class ParseTask extends SimpleModel {
     private String errorMessage;
     
     @Schema(description = "选项")
-    @TableField(value = "options", typeHandler = com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler.class)
+    @TableField(value = "options", typeHandler = com.lingyue.common.mybatis.PostgreSqlJsonbTypeHandler.class)
     private Object options;
     
     @Schema(description = "开始时间")