从JpaRepository

时间:2015-05-22 13:21:13

标签: spring spring-data spring-data-jpa spring-data-rest

我有以下存储库:

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与单独的存储库公开是不可能的,因为它不是一个被管实体。

1 个答案:

答案 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来记录执行此操作的最佳方式。