Spring Data JPA - Using SpEL variable #entityName to create a Generic Repository

[Last Updated: May 30, 2018]

In the last tutorial, we saw a use case for using SpEL variable #entityName. In this example we will see another use case, that is, to create a generic repository, say R, based on an abstract generic type, say T. If we define queries using @Query along with #entityName in such repository, then those queries will be inherited to the repositories extending R and are based on subtypes of T. That way we don't have to repeat the definition of query methods for the subtypes of T.
Let's understand that with an example.



public abstract class Task {
  private long id;
  private String name;
public class AsyncTask extends Task {
public class SyncTask extends Task {


package com.logicbig.example;

import java.util.List;

public interface TaskRepository<T extends Task> extends CrudRepository<T, Long> {

  @Query("SELECT t FROM #{#entityName} t WHERE = ?1")
  public List<T> findTaskByName(String taskName);

Note that we used @NoRepositoryBean in above interface. This annotation is used to exclude repository interfaces from being picked up by the framework and getting an instance being created.

package com.logicbig.example;

public interface AsyncTaskRepository extends TaskRepository<AsyncTask> {
package com.logicbig.example;

public interface SyncTaskRepository extends TaskRepository<SyncTask> {

Example Client

public class ExampleClient {

  private AsyncTaskRepository repoAsync;
  private SyncTaskRepository repoSync;

  public void run() {

      System.out.println(" -- finding async task  --");
      List<AsyncTask> list = repoAsync.findTaskByName("Cleaning");

      System.out.println(" -- finding sync task  --");
      List<SyncTask> list2 = repoSync.findTaskByName("Reporting");

Main class

public class ExampleMain {

  public static void main(String[] args) {
      AnnotationConfigApplicationContext context =
              new AnnotationConfigApplicationContext(AppConfig.class);
      ExampleClient exampleClient = context.getBean(ExampleClient.class);;
      EntityManagerFactory emf = context.getBean(EntityManagerFactory.class);
 -- finding async task  --
AsyncTask{id=2, name='Cleaning'}
-- finding sync task --
SyncTask{id=4, name='Reporting'}

Example Project

Dependencies and Technologies Used:

  • spring-data-jpa 2.0.7.RELEASE: Spring Data module for JPA repositories.
    Uses org.springframework:spring-context version 5.0.6.RELEASE
  • hibernate-core 5.3.1.Final: Hibernate's core ORM functionality.
    Implements javax.persistence:javax.persistence-api version 2.2
  • h2 1.4.197: H2 Database Engine.
  • JDK 1.8
  • Maven 3.3.9

Spring El, using #entityName to create a Generic Repository Select All Download
  • spring-data-jpa-spel-expression-generic-repo
    • src
      • main
        • java
          • com
            • logicbig
              • example
          • resources
            • META-INF

    See Also