I need to access current locale in Spring Repository using SpEL.
I have next Repository
:
@Repository
public interface RoomRepository extends JpaRepository<Room, Long> {
@Query(..."left join rc.roomClassTranslations rct on rct.language = ?#{SpEL expression})
List<RoomDTO> findAllRooms(Sort sort);
}
I tried several expressions but none of them worked.
#{@localeResolver.resolveLocale(#httpServletRequest).toLanguageTag()} "...)
In this expression httpServletRequest is null, if I change it to @httpServletRequest
, it will give an error that no bean is found. I also tried to rewrite it like this
#{LocaleContextHolder.getLocale().toLanguageTag()}
this will give next error:
EL1011E: Method call: Attempted to call method getLocale() on null context object.
So how to access current locale in SpEL expression?
CodePudding user response:
Spring support the usage of restricted SpEL template expressions in manually defined queries that are defined with @Query
.
Spring Data exposes an extension point EvaluationContextExtension
.
Spring Data JPA will pick up all beans of type EvaluationContextExtension
and use those to prepare the EvaluationContext
to be used to evaluate the SpEL expression defined in @Query
.
Let's implement the locale extension as an example.
@Component
public class LocaleEvaluationContextExtension
implements EvaluationContextExtension {
@Override
public Map<String, Object> getProperties() {
Map<String, Object> properties = new HashMap<>(
EvaluationContextExtension.super.getProperties());
return properties;
}
@Override
public String getExtensionId() {
return "locale";
}
@Override
public Object getRootObject() {
return LocaleContextHolder.getLocale();
}
}
The query method definition should be:
@Query(..."left join rc.roomClassTranslations rct on "
"rct.language = ?#{locale.language})
List<RoomDTO> findAllRooms(Sort sort);