Spring Expression Language (SpEL) est is used often in Spring Security project. But Spring Data also supports it.

Looking for a better data engineering position and skills?
You have been working as a data engineer but feel stuck? You don't have any new challenges and are still writing the same jobs all over again? You have now different options. You can try to look for a new job, now or later, or learn from the others! "Become a Better Data Engineer" initiative is one of these places where you can find online learning resources where the theory meets the practice. They will help you prepare maybe for the next job, or at least, improve your current skillset without looking for something else.
๐ I'm interested in improving my data engineering skillset
In this article we'll discover how to implement the queries containing SpEL fragments. In the first part we'll see some theoretical aspects with the classes participating in handling of SpEL expressions. The next part will show how to use SpEL fragments withing Spring Data JPA queries.
SpEL and Spring Data queries
Thanks to SpEL we can write the expressions able to be evaluated by Spring. They can be used in several situations. As we mentioned earlier, they can be used in Spring Security project to check if given user has the rights to access protected element. But they can also be employed to save expressions in the database and evaluate them dynamically, at runtime.
In Spring Data, SpEL can be used to String-based queries. We can refer to current entity thanks to following expression #{#entityName}. It refers to entity handled by given repository. To see what is implemented, let's take a look at org.springframework.data.jpa.repository.query.ExpressionBasedStringQuery. This class extends from StringQuery and represents a query based on SpEL. The query is parsed in a standard way, through instance of org.springframework.expression.spel.standard.SpelExpressionParser class. After the parsing, generated query returned as a String and used inside @Query annotation as a normal, no-expression containing query String. Code in charge of this transformation looks like that:
StandardEvaluationContext evalContext = new StandardEvaluationContext(); evalContext.setVariable(ENTITY_NAME, metadata.getEntityName()); SpelExpressionParser parser = new SpelExpressionParser(); Expression expr = parser.parseExpression(query, ParserContext.TEMPLATE_EXPRESSION); Object result = expr.getValue(evalContext, String.class); return result == null ? query : String.valueOf(result);
Implement SpEL with Spring Data queries
As you see, the only supported value in SpEL queries is entityName (at least for the current, 1.6.0 version). We can use it to, for example, do not make a typo error, less application compile and see this mistake only after. So, let's write a simple JUnit case and execute it against #{#entityName} expression. First, it's our repository:
public interface ProductRepository extends CrudRepository<Product, Integer> { @Query("SELECT p FROM #{#entityName} p WHERE p.name = :name") public Product getByName(@Param("name") String name); }
As you can imagine, in our test case we'll want to get one product by its name. Make it to "milk" for example (before launching this test, a product with this name must be inserted into database) :
public class ProductRepositoryTest { @Autowired private ProductRepository productRepository; @Test public void milkTest() { Product milk = productRepository.getByName("milk"); assertTrue("Milk can't be null but it is", milk != null); assertTrue("Retreived product should be called 'milk', but is "+milk.getName(), milk.getName().equals("milk")); } }
The test should pass well. If it's not, maybe you don't have an appropriate version of Spring Data JPA project.
In this short article we saw the way of integrate SpEL expressions inside Spring Data queries. Actually it supports only the expression representing repository's entity. Thanks to it, we can avoid typos which are detectable only at runtime.