Search code examples
hibernatejpaspring-data-jpaquerydsl

How to apply query hints to SpringData/QueryDSL findAll


I am building a SpringData/QueryDSL base repository. I have the following set of classes:

@Entity
@Table(name="t_ows_jo")         
@NamedEntityGraphs({
    @NamedEntityGraph(
        name="graph.Jo",                                            
        attributeNodes={
            ...
        },
        subgraphs={
            ...
        }
    )
})
public class Jo  {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    protected Long id;

    private String  joNo;
    private String  vin;
    private Date    dateFiled;
    private Integer mileage;

    private Vehicle vehicle;
    private Dealer  dealer;
    private List<JoJobRequest>  jobRequest;
    private List<JoJobDone>     jobDone;

    ...
}

@NoRepositoryBean
public interface BaseRepository<Entity, ID extends Serializable> extends JpaRepository<Entity, ID>, QueryDslPredicateExecutor<Entity> {
    Entity retrieve(Map<String, Object> filters);

    ... more custom methods here


    List<Entity> listAll(Map<String, Object> qryParam, int pageStart, int pageSize, Sort sortOrder);
}

public class BaseRepositoryImpl<Entity, ID extends Serializable> extends QueryDslJpaRepository<Entity, ID> 
    implements  BaseRepository<Entity, ID> {

    @PersistenceContext
    private EntityManager entityManager;


    //...   more codes here


    @Override
    public List<Entity> listAll(Map<String, Object> qryParam, int pageStart, int pageSize, Sort sortOrder) {
        Page<Entity> entities = null;

        Pageable pageReq = new PageRequest(pageStart, pageSize, sortOrder); 

        BooleanBuilder where = new BooleanBuilder();

        //build where here using qryParam

        ... some more codes here

        //get a reference to JPAQuery and apply query hints
        //EntityGraph graph = getEm().getEntityGraph("graph.Jo");
        //query.setHint("javax.persistence.fetchgraph",graph);

        entities = findAll(where.getValue(), pageRequest); //<<-----<<<< I want to apply query hints here

        return entities.getContent();
    }   
}

The above BaseRepositoryImpl is working fine as desired. However, I would like to add query hints using EntityGraph something like:

//get a reference to JPAQuery and apply query hints
EntityGraph graph = getEntityManager().getEntityGraph("graph.Jo");
query.setHint("javax.persistence.fetchgraph",graph);

entities = findAll(where.getValue(), pageRequest); //<<-----<<<< I want to apply query hints here

Is it possible to get a reference to the JPAQuery of the findAll method so query hints can be applied?

How can I apply query hints to findAll?

I am using QueryDSL v3.6.5 and SpringData v1.8.2 with Hibernate v4.3.11.Final as the JPA engine.

Any help/suggestion would be greatly appreciated.

Thanks in advance. Mario


Solution

  • Yes this is possible. You can write your own findAll(), it's simple:

    @PersistenceContext
    private EntityManager em;
    
    public <T, Q extends EntityPathBase<T>> Page<T> findAll(Q path, Predicate predicate, Pageable pageable, EntityGraph fetchGraph) {
        Querydsl querydsl = new Querydsl(em, new PathBuilder<>(path.getType(), path.getMetadata()));
        JPAQuery countQuery = new JPAQuery(em).from(path).where(predicate);
        long total = countQuery.count();
    
        JPAQuery query = new JPAQuery(em).from(path).where(predicate);
        if (fetchGraph != null) {
            query.setHint(QueryHints.FETCHGRAPH, fetchGraph);
        }
        if ((pageable == null) || (total > pageable.getOffset())) {
            return new PageImpl<>(querydsl.applyPagination(pageable, query).list(path), pageable, total);
        } else {
            return new PageImpl<>(Collections.emptyList(), pageable, total);
        }
    }
    

    path - the generated Q-counterpart of the entity you querying for. E.g. QJo.jo.

    As you have JPAQuery instance you can set any options and hints you want.