Spring Data Rest自定义JpaRepository返回投影列表报错问题求助
解决Spring Data Rest返回投影列表时的PersistentEntity找不到错误
嘿,这个问题我之前踩过坑!你遇到的Couldn't find PersistentEntity for type class com.sun.proxy.$Proxy117错误,本质是Spring Data Rest处理投影集合时,没法把动态生成的代理投影类关联到原始的实体类上,而单个投影能正常工作是因为框架能从上下文直接推断出对应的实体信息。
下面是几个可行的解决方案:
1. 给投影接口明确指定目标实体
这是最关键的一步,一定要在投影接口上用@Projection注解的types属性绑定对应的实体类,让Spring Data Rest知道这个投影属于哪个实体:
import org.springframework.data.rest.core.config.Projection; @Projection(name = "entityProjection", types = {YourEntity.class}) // 替换成你的实体类 public interface YourProjection { // 定义需要暴露的字段方法,比如: String getUsername(); Integer getAge(); }
2. 仓库方法规范返回类型
在自定义查询方法中,直接返回List<YourProjection>,同时确保查询语句是针对原始实体类的:
import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.rest.core.annotation.RepositoryRestResource; @RepositoryRestResource(collectionResourceRel = "entities", path = "entities") public interface YourEntityRepository extends PagingAndSortingRepository<YourEntity, Long> { @Query("SELECT e FROM YourEntity e WHERE e.age > 18") // 针对实体类的查询 List<YourProjection> findAdultEntities(); }
3. 手动投影集合(自定义控制器方案)
如果上面的方法还是不行,可以放弃Spring Data Rest自动暴露的端点,自己写控制器手动处理投影,这样更灵活:
import org.springframework.data.rest.core.projector.PersistentEntityProjector; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; import java.util.stream.Collectors; @RestController @RequestMapping("/api/custom-entities") public class CustomEntityController { private final YourEntityRepository repository; private final PersistentEntityProjector projector; // 构造注入依赖 public CustomEntityController(YourEntityRepository repository, PersistentEntityProjector projector) { this.repository = repository; this.projector = projector; } @GetMapping("/adults") public List<?> getAdultProjections() { List<YourEntity> entities = repository.findAll(); // 手动为每个实体应用投影 return entities.stream() .map(entity -> projector.project(entity, YourProjection.class)) .collect(Collectors.toList()); } }
为什么单个投影没问题?
当返回单个投影对象时,Spring Data Rest可以从方法的返回类型、仓库的泛型参数等上下文信息,推断出投影对应的原始实体;但返回集合时,Java的类型擦除会让框架丢失泛型类型信息,无法直接关联到实体类,所以必须通过@Projection的types属性明确绑定,或者手动处理投影。
内容的提问来源于stack exchange,提问作者mahsum
相关产品推荐
相关产品推荐

