2015-05-22 3 views
1

У меня есть следующий репозиторий:Вернуться на заказ типизированный объект из JpaRepository

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. Expose CustomUser с отдельным хранилищем невозможно, поскольку он не является управляемым объектом.

+0

Это только для Spring Data Rest или вы вызываете этот метод также в разных местах. –

+0

@ M.Deinum Only Spring Data Rest. Ранее этот фрагмент кода работал нормально как автономный DAO – nKognito

+0

. Затем вы могли бы использовать [Прогнозы или Выдержки] (http://docs.spring.io/spring-data/rest/docs/current/reference/html/#projections-excerpts .projections) вместо того, чтобы делать это с JPA. –

ответ

1

Одна проблема с использованием Spring Data Rest - это когда вы попадаете в кромку края, и вы не знаете, попали ли вы в ошибку или вы находитесь за пределами области, для которой предназначена библиотека. В этом случае я думаю, что вы находитесь на грани того, что SDR будет легко делать для вас, и пришло время реализовать собственный контроллер.

Spring Data Rest ищет объект - в вашем случае пользователь - как возвращаемый тип для ВСЕХ методов в репозитории для раскрытия под/сущностями/поиском и разбивается, когда он не находит этот тип сущности. Пользователь, которого он хочет сериализовать, не существует, поэтому «Постоянная сущность не должна быть нулевой».

Путь вокруг этого состоит в том, чтобы написать простой @Controller с @RequestMapping для того же самого URL-адреса, который был открыт методом репозитория. Это переопределит генерируемую SDR-реализацию для этого URL-адреса, и из этого вы сможете вернуть все, что захотите.

Ваша реализация может выглядеть примерно так:

@Controller 
public class CustomUserController { 

    private final UserRepository repository; 

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

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

} 

Имейте в виду, что есть «рекомендуется» способ переопределить функциональность таким образом. Существует open issue, чтобы документировать лучший способ сделать это.

+0

Я также хотел бы добавить ссылку на этот похожий вопрос: http://stackoverflow.com/questions/28428573/how- к разоблачить-заказ DTO-падла-хранилищу с пружинным-данных остальное – Jay

Смежные вопросы