Spring Data JPA查询返回List<String>报错:Couldn't find PersistentEntity
这个问题我之前也碰到过,本质是Spring Data REST的自动资源装配逻辑在处理非实体返回类型时的限制导致的。Spring Data REST默认会尝试将Repository方法的返回值转换成PersistentEntityResource,但String不是JPA实体,没有对应的持久化元数据,所以抛出了Couldn't find PersistentEntity for type class java.lang.String!的异常。
下面给你两种针对性的解决方案,根据你的需求选择:
方案1:如果不需要通过REST接口暴露该方法
如果这个lookupStatusCodes()只是服务内部调用,不需要对外暴露REST接口,只需要给方法加上@RestResource(exported = false)注解,让Spring Data REST跳过对它的资源装配:
@RestResource(exported = false) @Query("select DISTINCT item.statusCode from Item item") public List<String> lookupStatusCodes();
方案2:需要通过REST接口返回该字符串列表
如果要对外提供这个接口,建议自定义Controller绕过Spring Data REST的自动处理,直接返回字符串列表:
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; @RestController @RequestMapping("/api/status-codes") public class StatusCodeController { private final ItemRepository itemRepository; // 构造函数注入Repository(Spring 4.3+支持) public StatusCodeController(ItemRepository itemRepository) { this.itemRepository = itemRepository; } @GetMapping public List<String> getStatusCodes() { return itemRepository.lookupStatusCodes(); } }
这样访问/api/status-codes就能直接拿到你需要的字符串列表,不会触发PersistentEntity的查找逻辑。
补充说明
为什么不能直接用Repository暴露这个方法?因为Spring Data REST的核心是围绕JPA实体设计的,它期望Repository方法返回的是实体(或实体的分页/集合),这样才能生成符合HAL规范的REST资源。当返回非实体类型时,它找不到对应的资源元数据,就会抛出异常。你的场景里结果集很小不需要分页,自定义Controller是最直接的解决方式。
内容的提问来源于stack exchange,提问作者jamey graham

