4

I'm looking for a way to add a QueryHint inside of a Specifications toPredicate method. As I'm only having access to Root<T>, CriteriaQuery<?> and CriteriaBuilder instances I'm wondering if this is even possible.

I'm also okay with setting a global default, so that the hint is applied to all queries globally, but I would prefer to somewhat add it inside of the Specification. Maybe hibernate has a property I didn't spot in it's hibernate.properties file to achieve that.

I know I could achieve that by overriding the JpaSpecificationExecutors corresponding method and annotate the method with @QueryHints, but as I would have to do that for all Repositories, I would prefer to not do that as it is somewhat error prone.

Thanks in advance.

cmdjulian
  • 123
  • 1
  • 1
  • 6

1 Answers1

2

It's possible but you have to apply Criteria API directly without Spring Data wrappers. Here is an example from Vlad Mihalcea's article.

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
 
CriteriaQuery<Post> criteria = builder.createQuery(Post.class);
Root<Post> fromPost = criteria.from(Post.class);
 
criteria.where(
    builder.in(
        fromPost.get("id")).value(Arrays.asList(1, 2, 3)
    )
);
 
List<Post> posts = entityManager
    .createQuery(criteria)
    .setHint("hint_name", "hint_value")
    .getResultList();

If you do want to stick to Spring Data Specification, you can try to use @QueryHints annotation.

public interface RobotRepositoryRobot extends JpaRepository<Robot, Long>, JpaSpecificationExecutor<Robot> {
    @Override
    @QueryHints(
        @QueryHint(name = "hint_name", value = "hint_value")
    )
    List<Robot> findAll(Specification<Robot> spec);
}

Though in this case, hints aren't dynamic.

Semyon Kirekov
  • 1,237
  • 8
  • 20