Spring Data Projection不生效及@CreationDate字段为null问题求助
我来帮你逐一解决这两个Spring Data相关的问题:
一、Spring Data Projection未生效的原因及解决
从你给出的返回结果来看,实际返回的是Category实体对象而非ShowCategoryDto投影对象(结果里包含了投影接口未定义的creationDate、lastModifiedDate、parentCategory字段),主要原因和解决办法如下:
实体类访问权限限制
你的Category实体类是包级访问权限(没有public修饰符),而Spring Data在处理投影时,需要通过反射访问实体的字段或getter方法。将Category类改为public就能解决这个基础访问问题:@Entity @Getter @DynamicUpdate @EqualsAndHashCode(of = "name") @NoArgsConstructor public class Category { // 添加public修饰符 // ... 原有代码保持不变 }投影接口方法的简化优化(可选)
你的ShowCategoryDto中getId()方法使用了@Value("#{target.id}"),其实只要实体类有对应的getId()getter方法(你的实体用了@GetterLombok注解,已经自动生成),可以直接简化为:public interface ShowCategoryDto { Long getId(); // 移除@Value注解,自动映射实体的getId()方法 String getName(); Set<ProductBasicDto> getProducts(); }显式指定查询触发投影(兜底方案)
如果上述调整后投影仍不生效,可以通过@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的审计功能,必须完成两步配置才能自动填充值:
为实体添加审计监听器
在Category实体类上添加@EntityListeners(AuditingEntityListener.class)注解,告诉JPA在实体创建或更新时触发审计逻辑:@Entity @Getter @DynamicUpdate @EqualsAndHashCode(of = "name") @NoArgsConstructor @EntityListeners(AuditingEntityListener.class) // 添加此注解 public class Category { // ... 原有代码保持不变 }全局开启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

