使用JpaSpecificationExecutor时使用QueryHint

我使用spring数据和JpaSpecificationExecutor::findAll方法来获取我的模型。 调用此方法时如何使用查询提示?
上面的源代码工作正常但我不能为我的JPA提供程序设置QueryHint(在我的例子中是EclipseLink)。

 @Repository public interface ProductRepository extends JpaRepository, JpaSpecificationExecutor { } @Service public class ProductService { @Autowired private ProductRepository productRepository; public List findByTitle(String locale, String titleToSearch) { return productRepository.findAll((Root root, CriteriaQuery query, CriteriaBuilder builder) -> { return builder.equal(builder.function("jsonb_extract_path_text", String.class, root.get("title"), builder.literal(locale)), titleToSearch); }); } } 

我使用spring-data使用Query Hints的方法如上,

 @Repository public interface ProductRepository extends JpaRepository, JpaSpecificationExecutor { @QueryHints(value = { @QueryHint(name = org.eclipse.persistence.config.QueryHints.BATCH_TYPE, value = "JOIN"), @QueryHint(name = org.eclipse.persistence.config.QueryHints.BATCH, value = "p.productCategory"), @QueryHint(name = org.eclipse.persistence.config.QueryHints.BATCH, value = "p.productFileList") }, forCounting = false) @Query("SELECT p FROM Product p") public List find(); } 

我也发现了这个尚未解决的问题。

当我想使用spring-data创建查询时,我遵循上面的算法。

1)查询是否已经由现有的spring-data接口提供 ,如CrudRepositoryPagingAndSortingRepositoryJpaRepository等?
示例: saveAndFlushfindAll方法,更多在文档中 。

 Product product = new Product(); // Setters.. productRepository.saveAndFlush(); 

2)我可以在方法名称中使用关键字创建方法吗?
示例: 计数 ,更多在文档中 。

 @Repository public interface ProductRepository extends JpaRepository { Long countByTitle(String title); List findByTitleLikeAndVisible(String title, boolean visible); } 

3)我可以创建一个编写JPQL的自定义查询方法吗?
示例: docs 。
在这种情况下,spring数据不会尝试使用方法名称中的关键字创建查询,因此方法名称可以是您想要的任何名称。

 @Repository public interface ProductRepository extends JpaRepository { @Query("SELECT COUNT(p) FROM Product p WHERE p.title=?1") Long countByTitle(String title); @Query("SELECT p FROM Product p WHERE p.title LIKE :title AND visible=true") List findByTitleLikeAndVisibleTrue(@Param("title") String title); } 

4)我想要变量列名称或变量的条件吗? 然后解决方案是规范。
示例: docs , 所以回答

 @Repository public interface ProductRepository extends JpaRepository, JpaSpecificationExecutor { } @Service public class ProductService { @Autowired private ProductRepository productRepository; public List findByColumn(String columnName, Object value) { return productRepository.find((Root root, CriteriaQuery query, CriteriaBuilder builder) -> { return builder.and(builder.equal(root.get(columnName), value)); }); } } 

5)我想要更多吗? 解决方案是获取EntityManager并像使用它一样使用它而不使用spring数据库。 (这就是这个问题的答案)
示例: 所以回答 ,更多在文档中

 // Create an interface and add the methods you wish to use with EntityManger. public interface ProductRepositoryExt { public List findByTitle(String title); } // Implement the interface you created. Be careful the class name must be identical to the spring-data @Repository interface with the "Impl" appended. public class ProductRepositoryImpl implements ProductRepositoryExt { @PersistenceContext private EntityManager em; @Override public List findByTitle(String title) { // em.getTransaction().begin(); String sql = "SELECT p FROM Product p WHERE p.title=:title')"; TypedQuery query = em.createQuery(sql, Product.class); query.setParameter("title", title); // Add the query hints you wish.. query.setHint(org.eclipse.persistence.config.QueryHints.BATCH_TYPE, "JOIN"); query.setHint(org.eclipse.persistence.config.QueryHints.BATCH, "p.productCategory"); return query.getResultList(); // em.getTransaction().commit(); } } // Extend this interface from your spring-data @Repository interface. @Repository public interface ProductRepository extends JpaRepository, ProductCategoryRepositoryExt { }