关于spring:从JpaRepository返回自定义类型的对象

Return custom-typed object from JpaRepository

我有以下存储库:

1
2
3
4
5
6
public interface UserRepository extends BaseDAO<User> {
    Collection<User> findByEmail(@Param("email") String email);

    @Query("select new com.data.CustomUser(upper(substring(u.lastName, 1, 1)) as initial, count(*)) from User u join u.chats c where c.business=:business group by upper(substring(u.lastName, 1, 1)) order by initial")
    List<CustomUser> getContactsIndex(@Param("email") String email);
}

随Spring Data REST一起公开。 User对象是一个受管实体,而CustomUser不是,您可以看到,它是使用自定义查询即时构建的。

一旦我想调用该函数,它将失败,并出现Persistent entity must not be a null!异常。有什么办法可以实现这种行为?

P.S。无法使用单独的存储库公开CustomUser,因为它不是托管实体。


使用Spring Data Rest的一个挑战是当您遇到一个极端的情况时,您不知道自己是否遇到了错误,或者您是否不在该库的预期范围之内。在这种情况下,我认为您处于SDR可以轻松为您做的事情的边缘,现在该实现您自己的控制器了。

Spring Data Rest正在寻找一个实体(在您的情况下为User)作为存储库中要显示在/ entities / search下的所有方法的返回类型,并在找不到该实体类型时中断。要序列化的用户不存在,因此"持久实体不能为空"。

解决此问题的方法是编写一个简单的@Controller,该@Controller具有与存储库方法公开的完全相同的URL的@RequestMapping。这将覆盖该URL的SDR生成的实现,并且您可以从中返回所需的任何内容。

您的实现可能看起来像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Controller
public class CustomUserController {

    private final UserRepository repository;

    @Inject
    public CustomUserController(UserRepository repo) {
        repository = repo;
    }

    @RequestMapping(value ="/users/search/getContactsIndex", method = GET, produces = {MediaType.APPLICATION_JSON_VALUE})
    public @ResponseBody List<CustomUser> getContactsIndex(@RequestParam String email) {
        return repository.getContactsIndex(email);
    }

}

请注意,有一种"推荐\\"方法可以以这种方式覆盖功能。有一个公开的问题来记录实现此目的的最佳方法。