Antonio Diaz
Antonio Diaz

Reputation: 173

Dynamic JPA querys

I'm pretty new in JPA/Hibernate and spring boot, and I'd like to do dynamic querys depeding on the received params. I was following this approach https://www.baeldung.com/spring-data-jpa-query , but I have a doubt when it say : "Also, we need to make sure to include the Impl postfix in the class name. Spring will search the UserRepositoryCustom implementation as UserRepositoryCustomImpl. Since fragments are not repositories by themselves, Spring relies on this mechanism to find the fragment implementation."

What doest it means ? How can I include the Impl postfix in the class name?

Thanks

Upvotes: 0

Views: 119

Answers (2)

Tanmoy Majumdar
Tanmoy Majumdar

Reputation: 458

It means if you need any custom methods in your repository you need to declare an interface as follows

public interface UserRepositoryCustom {
List<User> findUserByEmails(Set<String> emails);
}

and now you need to provide the implementation of the interface as follows

public class UserRepositoryCustomImpl implements UserRepositoryCustom {

@PersistenceContext
private EntityManager entityManager;

@Override
public List<User> findUserByEmails(Set<String> emails) {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<User> query = cb.createQuery(User.class);
    Root<User> user = query.from(User.class);

    Path<String> emailPath = user.get("email");

    List<Predicate> predicates = new ArrayList<>();
    for (String email : emails) {
        predicates.add(cb.like(emailPath, email));
    }
    query.select(user)
        .where(cb.or(predicates.toArray(new Predicate[predicates.size()])));

    return entityManager.createQuery(query)
        .getResultList();
}
}

spring will try to find the implementation of the interface with the Impl postfix and here it is UserRepositoryCustomImpl(interface name : UserRepositoryCustom + Impl(postfix)). if you prefer another postfix you can add @EnableJpaRepositories( repositoryImplementationPostfix = "Impl2", ) on your configuration here Impl2 is your custom post fix. So your implementation class name should be UserRepositoryCustomImpl2

Upvotes: 1

zlaval
zlaval

Reputation: 2047

Suppose you have an entity Person. You create a repository interface to that.

public interface PersonRepository extends JpaRepository<Person, String>{}

Then you need a custom logic. So you create a custom repository interface:

@NoRepositoryBean
public interface CustomPersonRepository { 
   [...]
}

And the implementation class with Impl postfix:

@Repository
public class CustomPersonRepositoryImpl implements CustomPersonRepository{
   
   @PersistenceContext
   private EntityManager entityManager;

   [...]
}

Now you add the custom interface to the original repository interface:

public interface PersonRepository extends JpaRepository<Person, String>,CustomPersonRepository{

}

When you @Autowired the PersonRepository interface, and call a method on the injected beans which belongs to the CustomPersonRepository, Spring will use the method of the CustomPersonRepositoryImpl.

So the name of the implementation class must be the same name as the custom interface + an Impl at the end. You can parameterize that postfix anyway with the repositoryImplementationPostfix property in the @EnableJpaRepositories annotation.

Upvotes: 0

Related Questions