2017-02-01 6 views
3

Я пытаюсь запустить собственный запрос по методу репозитория, чтобы он возвращал результаты с некоторыми значениями. С JPQL было слишком сложно, поэтому вместо этого я выбрал собственный запрос.Подзапрос репозитория Spring JPA в собственном запросе

Repository

@RepositoryRestResource(collectionResourceRel="projects", path="projects") 
interface ProjectRepository extends BaseRepository<Project, Long>, ProjectRepositoryCustom { 

    @Query(
     value="SELECT p.id, p.user_id, p.title, p.description, p.created_on, p.version,(SELECT COUNT(0) FROM projectparts WHERE project_id = p.id) AS parts,(SELECT COUNT(0) FROM requests WHERE project_id = p.id) AS requests FROM projects AS p ORDER BY ?#{#pageable}", 
     countQuery="SELECT COUNT(0) FROM projects", 
     nativeQuery=true 
    ) 
    Page<Project> findAll(Pageable pageable) 

} 

Объект имеет 2 свойства аннотированные с @Transient так, что информация не сохраняется в базе данных. Все данные возвращаются штрафом, за исключением 2 переходных свойств, которые возвращают значение null для значений. Когда я копирую запрос с консоли и вставляю его в MySQL Workbench, результаты ожидаются, и я вижу нужные мне счетчики. Во всяком случае, не уверен, есть ли что-то еще, что нужно сделать, чтобы заставить этот собственный запрос работать как аннотация. Я жестко закодировал значение в подзапросе SELECT 55 FROM..., чтобы увидеть, была ли проблема с подсчетом, и он по-прежнему возвращается как null. Я выполнил запрос в Workbench, и он работает нормально.

Я попытался изменить тип свойства переходного процесса от Integer, Long, BigInteger, long, int..., и ничто из этого не изменило ситуацию. Поскольку я использую Groovy, я также попробовал def, чтобы Groovy вывести тип, и это тоже не сработало.

Я также попытался запустить проект с терминала, и он все еще не работает. Я пробовал это на Mac и Linux, и мне не повезло с отображением результатов подсчетов.

ответ

2

Это не сработает. Вы можете использовать SQLConstructorExpression, однако возвращенные экземпляры будут неуправляемыми, что является серьезным недостатком.

Лучшим вариантом является создание простого представления БД, которое содержит фрагменты итоговой информации для Проекта. Вы можете сопоставить объект проекта как с его таблицей, так и с соответствующим сводным представлением, используя функциональность JPA @SecondaryTable.

https://en.wikibooks.org/wiki/Java_Persistence/Tables#Example_mapping_annotations_for_an_entity_with_multiple_tables

Дополнительным преимуществом является то, что вы можете сортировать и запрос на итоговые значения, как и для любого другого имущества.

Обновлено отображение:

@Entity 
@Table(name = "projects") 
@SecondaryTable(name = "projects_summary_vw") 
public class Project{ 

    //use Integer rather than int to avoid issue outlined here: 
    //http://stackoverflow.com/a/37160701/1356423 

    @Column(name = "parts", table = "projects_summary_vw", 
      insertable="false", updateable="false") 
    private Integer partsCount; 

    @Column(name = "requests", table = "requestsCount" 
      insertable="false", updateable="false") 
    private Integer requestsCount; 

    //other mappings as required 
} 

Нет пользовательского запроса требуется:

@RepositoryRestResource(collectionResourceRel="projects", 
     path="projects") 
interface ProjectRepository extends BaseRepository<Project, Long>, 
     ProjectRepositoryCustom { 

} 

Альтернативное решение, не JPA совместимый может использовать некоторые поставщика определенное расширение, а не вид. Hibernate, например, имеет @Formula аннотацию, которая может быть использована:

https://docs.jboss.org/hibernate/orm/5.1/javadocs/org/hibernate/annotations/Formula.html

@Entity 
@Table(name = "projects") 
public class Project{ 

    @Formula("my count query as native sql") 
    private Integer partsCount; 

    @Formula("my count query as native sql") 
    private Integer requestsCount; 

    //other mappings as required 
} 
+0

спасибо за обратную связь, я должен дать эти опции некоторые мысли. Я почти думаю о том, чтобы позволить JPA создавать столбцы, хотя я их не буду использовать. –

+0

Не надо. Представление будет хорошо работать и даст вам много других преимуществ. –

+1

Вы говорите об использовании 'MySQL View' и просто используете' @ SecondaryTable' для сопоставления дополнительных столбцов? –