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

Spring Data Projection不生效及@CreationDate字段为null问题求助

问题分析与解决方案

我来帮你逐一解决这两个Spring Data相关的问题:


一、Spring Data Projection未生效的原因及解决

从你给出的返回结果来看,实际返回的是Category实体对象而非ShowCategoryDto投影对象(结果里包含了投影接口未定义的creationDate、lastModifiedDate、parentCategory字段),主要原因和解决办法如下:

  1. 实体类访问权限限制
    你的Category实体类是包级访问权限(没有public修饰符),而Spring Data在处理投影时,需要通过反射访问实体的字段或getter方法。将Category类改为public就能解决这个基础访问问题:

    @Entity
    @Getter
    @DynamicUpdate
    @EqualsAndHashCode(of = "name")
    @NoArgsConstructor
    public class Category { // 添加public修饰符
        // ... 原有代码保持不变
    }
    
  2. 投影接口方法的简化优化(可选)
    你的ShowCategoryDto中getId()方法使用了@Value("#{target.id}"),其实只要实体类有对应的getId() getter方法(你的实体用了@Getter Lombok注解,已经自动生成),可以直接简化为:

    public interface ShowCategoryDto {
        Long getId(); // 移除@Value注解,自动映射实体的getId()方法
        String getName();
        Set<ProductBasicDto> getProducts();
    }
    
  3. 显式指定查询触发投影(兜底方案)
    如果上述调整后投影仍不生效,可以通过@Query显式指定要查询的字段,强制触发投影逻辑:

    interface CategoryRepository extends Repository<Category, Long> {
        @Query("SELECT c.id as id, c.name as name, c.products as products FROM Category c")
        Set<ShowCategoryDto> findAll();
    
        @Query("SELECT c.id as id, c.name as name, c.products as products FROM Category c WHERE c.id = :id")
        Optional<ShowCategoryDto> findOptionalById(Long id);
    
        // ... 其他方法保持不变
    }
    

二、@CreationDate和@LastModifiedDate字段为null的原因及解决

这两个注解属于Spring Data JPA的审计功能,必须完成两步配置才能自动填充值:

  1. 为实体添加审计监听器
    在Category实体类上添加@EntityListeners(AuditingEntityListener.class)注解,告诉JPA在实体创建或更新时触发审计逻辑:

    @Entity
    @Getter
    @DynamicUpdate
    @EqualsAndHashCode(of = "name")
    @NoArgsConstructor
    @EntityListeners(AuditingEntityListener.class) // 添加此注解
    public class Category {
        // ... 原有代码保持不变
    }
    
  2. 全局开启JPA审计功能
    在你的Spring Boot主类(或任意配置类)上添加@EnableJpaAuditing注解,启用全局的审计支持:

    @SpringBootApplication
    @EnableJpaAuditing // 添加此注解
    public class YourApplication {
        public static void main(String[] args) {
            SpringApplication.run(YourApplication.class, args);
        }
    }
    

另外提醒:你的creationDate和lastModifiedDate字段添加了@Setter注解,这其实没必要——审计功能会自动填充这两个字段,手动设置反而可能覆盖自动生成的值,建议移除这两个字段的@Setter:

// 移除@Setter注解
@CreatedDate
private LocalDateTime creationDate;

// 移除@Setter注解
@LastModifiedDate
private LocalDateTime lastModifiedDate;

内容的提问来源于stack exchange,提问作者minizibi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:08:01