我有以下存储库:
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
与单独的存储库公开是不可能的,因为它不是一个被管实体。
答案 0 :(得分:1)
使用Spring Data Rest的一个挑战是,当您遇到边缘情况并且您不知道自己是否遇到了错误,或者您是否超出了库的范围打算用于。在这种情况下,我认为您处于SDR将为您轻松做的事情的边缘,并且是时候实施您自己的控制器了。
Spring Data Rest正在寻找一个实体 - 在您的情况下是一个用户 - 作为存储库中所有方法的返回类型,在/ entities / search下公开,并在它找不到该实体类型时中断。它想要序列化的用户不在那里,因此&#34; Persistent实体不能为空&#34;。
解决这个问题的方法是编写一个简单的@Controller,它具有@RequestMapping,用于存储库方法公开的完全相同的url。这将覆盖该URL的SDR生成实现,并且可以从中返回您想要的任何内容。
您的实施可能如下所示:
@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);
}
}
请注意,有一个&#34;推荐&#34;以这种方式覆盖功能的方法。有open issue来记录执行此操作的最佳方式。