2015-03-18 3 views
2

Я работаю над Spring Data JPA, и у меня есть интерфейс репозитория, который реализует JpaRepository.Spring Data JPA @Query с spel в запросе IN

Я уже написал этот запрос, который работает отлично:

@Query ("FROM Person p " + 
     "LEFT JOIN p.relatedContractRoleAttributions rcras " + 
     "WHERE rcras.contract.id = :#{#contract.id} " + 
     "AND rcras.relatedContractRole.code = :#{#code}") 
Person findByContractAndRelatedContractRole(@Param ("contract") Contract contract, @Param ("code") String code); 

Теперь я хочу написать еще один запрос, который можно найти в более чем один код, так что я написал этот вопрос:

@Query ("FROM Person p " + 
     "LEFT JOIN p.relatedContractRoleAttributions rcras " + 
     "WHERE rcras.contract.id = :#{#contract.id} " + 
     "AND rcras.relatedContractRole.code IN (:#{#codes})") 
List<Person> findByContractAndRelatedContractRoles(@Param ("contract") Contract contract, @Param ("codes") String... codes); 

Но при запуске приложения у меня есть эта ошибка:

Caused by: org.hibernate.QueryException: unexpected char: '#' [FROM com.krgcorporate.core.domain.access.Person p LEFT JOIN p.relatedContractRoleAttributions rcras WHERE rcras.contract.id = :#{#contract.id} AND rcras.relatedContractRole.code IN (:__$synthetic$__2)] 

У вас есть идеи, почему?

Благодарим за помощь.

ответ

1

Я считаю, что есть проблема в org.springframework.data.jpa.repository.query.StringQuery. весна-данные JPA-1.7.2.RELEASE (линии 250..259)

case IN: 
    if (parameterIndex != null) { 
     checkAndRegister(new InParameterBinding(parameterIndex, expression), bindings); 
    } else { 
     checkAndRegister(new InParameterBinding(parameterName, expression), bindings); 
    } 
    result = query; 
    break; 

Так что, когда StringQuery связывает «в» параметра с SPEL он перекрывает строки результата запроса со строкой в ​​вашем @Query аннотации. И затем он заменяет «в» SPEL новой привязкой.

Если изменить

"WHERE rcras.contract.id = :#{#contract.id} " + 
     "AND rcras.relatedContractRole.code in :#{#code}" 

в

"WHERE rcras.relatedContractRole.code in :#{#code}" + 
     "AND rcras.contract.id = :#{#contract.id} " 

это исправить вашу проблему

UPDATE: SpingDataJpa команда зафиксировала его. https://jira.spring.io/browse/DATAJPA-712

1

Для статьи JPA in вы не должны писать скобки. (Такой же вопрос такой же ответ здесь https://stackoverflow.com/a/4379008/280244)

@Query ("FROM Person p " + 
    "LEFT JOIN p.relatedContractRoleAttributions rcras " + 
    "WHERE rcras.contract.id = :#{#contract.id} " + 
    "AND rcras.relatedContractRole.code IN :#{#codes)") 

И если честно: я никогда не видел этот синтаксис :#{#PARAM} раньше, я знаю только :PARAM. - но когда он работает в другом запросе будет работать в следующей слишком


@Franck Yapadesouci Anso: в соответствии с вашим комментарием: вы уверены, что вы можете использовать выражение SPEL таким образом - попробуйте это путь JPA.

@Query ("SELECT p FROM Person p " +  //+SELECT p 
    "LEFT JOIN p.relatedContractRoleAttributions rcras " + 
    "WHERE rcras.contract = :contract" + //without ID and SPEL 
    "AND rcras.relatedContractRole.code IN :codes") //without brackets and SPEL 
+0

Я пробовал без кронштейна, и у меня такая же ошибка. С другой стороны, вы можете перейти к документации. 3.3.6. Использование выражений SpEL здесь: http://docs.spring.io/spring-data/jpa/docs/current/reference/html/ –

+0

@Franck Yapadesouci Anso: Do вы используете JPA? – Ralph

+0

Разрешения @Ralph 'Spel' разрешены. Проверьте https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions и http://docs.spring.io/spring-data/jpa/docs. /current/reference/html/#jpa.query.spel-expressions – geoand

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