2017-02-01 1 views
0

Недавно я переключился с JEE на Spring Boot, и я люблю его до сих пор. Но я столкнулся с небольшой проблемой. У меня есть этот метод, который извлекает ленивые ссылки, которые используются, чтобы посмотреть что-то вроде этого:Весенние данные динамические @Query на основе параметров возможны?

public Foo getParentWithChildren(long id, boolean isFetchChild, boolean isFetchPets) { 
    StringBuilder sql = new StringBuilder(); 
    sql.append("select DISTINCT(p) from Parent p"); 
    if(isFetchChild) { 
     sql.append(" left join p.child c"); 
    } if(isFetchPets) { 
     sql.append(" left join p.pets pts"); 
    } 

    sql.append(" where p.id=:id"); 

    TypedQuery<Foo> query = em.createQuery(sql.toString(), Foo.class); 
    query.setParameter("id", id); 
    return query.getSingleResult(); 
} 

Теперь с весенними данными и их удивительными интерфейсами я хотел бы сделать что-то simlar с помощью аннотаций @Query на границе вместо того, чтобы написать пользовательскую реализацию. Но возможно ли что-то подобное использовать только с интерфейсом.

В приведенном ниже примере, очевидно, не работает, но я надеюсь, вы понимаете, что я пытаюсь acchieve

@Query("select distinct(p) from Parent p " + 
     (fetchChild ? " left join p.child c" : "") + 
     (fetchPets ? " left join p.pets pts" : "") + 
     " where p.id=:id") 
Foo getParentWithChildren(@Param("id") long id, @Param("fetchChild") boolean isFetchChild, @Param("fetchPets") boolean isFetchPets); 

я что-то подобное возможно?

+1

Нет, но если это ваш точный случай, вы можете создать 2 метода в интерфейсе и вызвать соответствующий один в соответствии с 'isFetchChild'. –

+0

На самом деле реальный родитель имеет 5 детей, например 5 булевых параметров. И есть разные комбинации. Иногда вам нужен ребенок 1 и 3, иногда только 4, иногда все 5 и т. Д. Итак, мне придется писать методы для всех возможных сценариев? – Johan

ответ

1

Вы можете создать несколько методов в интерфейсе и использовать функциональные возможности EntityGraph введен в JPA 2.1, который Spring Data JPA поддерживает различные способы:

http://docs.spring.io/spring-data/jpa/docs/1.11.0.RELEASE/reference/html/#jpa.entity-graph

public interface FooRepository extends JpaRepository<Foo, Long>{ 

    @EntityGraph(attributePaths = { "children" }) 
    @Query("select f from Foo f where f.id = :id") 
    Foo getFooWithChildren(@Param("id") long id); 

    @EntityGraph(attributePaths = { "pets" }) 
    @Query("select f from Foo f where f.id = :id") 
    Foo getFooWithPets(@Param("id") long id); 

    @EntityGraph(attributePaths = { "children", "pets" }) 
    @Query("select f from Foo f where f.id = :id") 
    Foo getFooWithChildrenAndPets(@Param("id") long id); 
} 

Одна проблемы с этим вам нужно повторите запрос для каждого метода. Возможность передавать графы сущности в качестве параметров метода запроса представляется полезной функциональностью, отсутствующей в модуле Spring Data JPA.

Я поднял на билет на это некоторое время назад, но не обновление еще:

https://jira.spring.io/browse/DATAJPA-645?filter=-2

Ссылка в ответ на этот вопрос Spring Data JPA And NamedEntityGraphs однако не указывает на расширение в ниже, что позволяет нам сделать именно это :

https://github.com/Cosium/spring-data-jpa-entity-graph

с помощью этого расширения код упрощается:

public interface FooRepository extends JpaEntityGraphRepository<Foo, Long>{ 

} 

и называют его:

Foo foo = fooRepository.findOne(1L, 
       new DynamicEntityGraph(Arrays.asList({"children"); 

Foo foo = fooRepository.findOne(1L, 
       new DynamicEntityGraph(Arrays.asList({"children", "pets"}); 
+0

Спасибо! я проверю это. Вопрос: являются ли ссылочные объекты, получаемые внутренним соединением по умолчанию? если это так, я могу указать, что мне нужно левое соединение или какой-либо другой тип? – Johan