You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot JPA如何修改PostgreSQL中JSON类型字段值

解决Spring Boot JPA更新PostgreSQL JSON字段的问题

问题背景

使用PostgreSQL数据库时,直接通过SQL工具执行update course_entity set list_id_professors = '[1,2]'::json where id = 1;可正常更新JSON字段,但在JPA的@Query中添加::json会报错;尝试将实体类字段改为Integer[]类型也无法正常工作,需要找到JPA中更新PostgreSQL JSON字段的正确实现方案。

用户当前的配置如下:

Maven依赖配置

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <scope>runtime</scope>
</dependency>
<!-- JSON处理依赖 -->
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20230227</version>
</dependency>

方言配置

spring:
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQLDialect
    show-sql: 'true'
    hibernate:
      ddl-auto: update

实体类定义

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Slf4j
public class CourseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(columnDefinition = "json")
    private String list_id_professors;
}

Repository接口

import jakarta.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.Optional;

@Repository
public interface SqlCourseRepository extends JpaRepository<CourseEntity, Integer>, JpaSpecificationExecutor {

    @Transactional
    @Modifying
    @Query("update CourseEntity set list_id_professors = :list_id_professors where id = :id")
    Integer updateCourseListIdProfessors(@Param(value = "id") Integer id, @Param(value = "list_id_professors") String list_id_professors);
}

可行解决方案

方案1:使用原生SQL执行更新

JPQL是跨数据库的查询语言,不支持PostgreSQL专属的::json类型转换语法,因此需要改用原生SQL,在@Query中添加nativeQuery=true即可:

修改Repository中的更新方法:

@Transactional
@Modifying
@Query(value = "update course_entity set list_id_professors = :list_id_professors::json where id = :id", nativeQuery = true)
Integer updateCourseListIdProfessors(@Param("id") Integer id, @Param("list_id_professors") String list_id_professors);

这样就能直接使用PostgreSQL的类型转换语法,避免JPQL解析报错。

方案2:将JSON字段映射为Java集合类型(更优雅)

无需手动处理JSON字符串,让Hibernate自动完成JSON与Java类型的序列化/反序列化,步骤如下:

1. 调整实体类字段映射

如果需要映射为List<Integer>:

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Slf4j
public class CourseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(columnDefinition = "json")
    @Type(type = "com.vladmihalcea.hibernate.type.json.JsonType")
    private List<Integer> list_id_professors;
}

如果需要映射为Integer[]:

@Column(columnDefinition = "json")
@Type(type = "com.vladmihalcea.hibernate.type.json.JsonType")
private Integer[] list_id_professors;

2. 引入Hibernate JSON类型依赖(若需要)

如果Spring Boot版本未自动包含相关类型支持,需添加hibernate-types依赖:

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-52</artifactId>
    <version>2.20.0</version>
</dependency>

3. 简化Repository方法

此时可以直接使用Spring Data JPA的默认方法,或编写更简洁的JPQL:

// 方法1:使用默认save方法更新
CourseEntity save(CourseEntity course);

// 方法2:自定义JPQL更新(自动处理JSON转换)
@Transactional
@Modifying
@Query("update CourseEntity set list_id_professors = :list where id = :id")
Integer updateCourseListIdProfessors(@Param("id") Integer id, @Param("list") List<Integer> list);

方案3:通过EntityManager执行原生查询

如果需要更灵活的操作,可直接注入EntityManager执行原生SQL:

  1. 创建自定义Repository接口:
public interface CourseCustomRepository {
    Integer updateCourseListIdProfessors(Integer id, String jsonList);
}
  1. 实现自定义接口:
@Repository
public class CourseCustomRepositoryImpl implements CourseCustomRepository {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    @Transactional
    public Integer updateCourseListIdProfessors(Integer id, String jsonList) {
        Query query = entityManager.createNativeQuery(
            "update course_entity set list_id_professors = ?1::json where id = ?2"
        );
        query.setParameter(1, jsonList);
        query.setParameter(2, id);
        return query.executeUpdate();
    }
}
  1. 让原Repository继承自定义接口:
@Repository
public interface SqlCourseRepository extends JpaRepository<CourseEntity, Integer>, JpaSpecificationExecutor, CourseCustomRepository {
    // 原有方法...
}

问题原因说明

  • JPQL中使用::json报错:JPQL是跨数据库的抽象查询语言,不识别PostgreSQL专属的类型转换语法,必须使用原生SQL才能执行该操作。
  • 直接改为Integer[]失败:默认情况下Hibernate无法自动将Java数组映射到PostgreSQL的JSON类型,需要显式指定@Type注解来处理JSON的序列化与反序列化逻辑。

内容的提问来源于stack exchange,提问作者Alvaro Guillen Gonzalez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:07:05