通过 JPA 标准查询从 SQL 视图获取列表时出错

Posted

技术标签:

【中文标题】通过 JPA 标准查询从 SQL 视图获取列表时出错【英文标题】:Error in getting list from SQL view through JPA Creteria Query 【发布时间】:2015-11-15 07:07:53 【问题描述】:

我在 mysql 数据库中创建了 SQL 视图。我正在编写 Web 服务以根据用户搜索条目使用 JPA 显示列表。休眠查询在控制台中正确执行,但在高级休息客户端中检查时未显示列表。请检查下面的所需代码:

实体类:

@Entity
@Table(name = "tbi_datadiscovery_detail_view"/*, catalog = "timebound"*/)
public class TbiDDDetailView implements java.io.Serializable 

    // Fields
    @Id
    @Column(name = "dd_metric_id")
    @GeneratedValue(generator = "gen")
    @GenericGenerator(name = "gen", strategy = "foreign", parameters = @Parameter(name = "property", value = "ddConfigId"))
    private Integer ddConfigId;  

    @Column(name="dd_metric_name")
    private String  metricName;

    @Column(name="dd_type")
    private String ddType;

    @Column(name="dd_name")
    private String ddName;

    @Column(name="discovery_id")
    private Integer discoveryId;

    @Column(name="key_words")
    private String keywords;

    @OneToOne
    @PrimaryKeyJoinColumn
    private TbiDDConfigMaster tbiDDConfigMaster;  

//setters & getters

  

JPA 存储库:

public interface TbiDDDetailViewDao extends CrudRepository<TbiDDDetailView, Integer>, JpaRepository<TbiDDDetailView, Integer> 

    @Query("select v from TbiDDDetailView v,TbiDDConfigMaster t where v.ddConfigId = t.ddConfigId and t.domainId=?1 and v.metricName LIKE %?2% or t.keywords LIKE %?2%")
List<TbiDDDetailView> findByDomainIdAndMetricNameLike(Integer domainId,String metricName);

  

服务实现:

public TbiDDDetailViewListResponse getViewMatrics(List sortProperties, List sortTypes,
        List operator, List value, List property, int page, int limit,
        Integer domainId, String searchString) 

    TbiDDDetailViewListResponse res = new TbiDDDetailViewListResponse();
    List<TbiDDDetailView> tbiDDDetailViews  = tbiDDDetailViewDao.findByDomainIdAndMetricNameLike(domainId, searchString);

        CriteriaBuilder cb=em.getCriteriaBuilder();
        CriteriaQuery<TbiDDDetailView> qry =cb.createQuery(TbiDDDetailView.class);
        Root root = qry.from(TbiDDDetailView.class);
        Root config = qry.from(TbiDDConfigMaster.class);

        List creteriaList = new ArrayList<>();
        Predicate predicate1 = cb.equal(root.get("tbiDDConfigMaster").get("ddConfigId"), config.get("ddConfigId"));
        creteriaList.add(predicate1);

        Predicate predicate2 = cb.equal(root.get("tbiDDConfigMaster").get("ddConfigId"), domainId);
        creteriaList.add(predicate2);

        Predicate predicate3 = cb.like(cb.upper(root.get("metricName")),searchString);
        creteriaList.add(predicate3); 

        CriteriaQuery<TbiDDDetailView> criteriaQuery = qry.select(cb.construct(TbiDDDetailView.class, root.get("ddConfigId"),root.get("metricName"),root.get("ddType"),
                root.get("ddName"),root.get("discoveryId")));


        List<Order> orderList = new ArrayList<>();
        orderList = getSort(cb,root,sortProperties, sortTypes, null);

        qry.where(cb.and((Predicate[]) creteriaList.toArray(new Predicate[0])));

        int start=0;
        if(limit != 0) 
        start=(page-1)*limit;

        TypedQuery<TbiDDDetailView> tq = em.createQuery(qry);
        tbiDDDetailViews = tq.setFirstResult(start).setMaxResults(limit).getResultList();
        TypedQuery<TbiDDDetailView> queryTotal = em.createQuery(criteriaQuery);
        long totalRecords = (long) queryTotal.getResultList().size();

        List<DDDetailViewResponse> details = new ArrayList<>();

        if(tbiDDDetailViews!=null)
        
            for(TbiDDDetailView t : tbiDDDetailViews)
                DDDetailViewResponse detailView = new DDDetailViewResponse();
                detailView.setDdMetricId(t.getDdConfigId());
                detailView.setDdMetricName(t.getMetricName());
                detailView.setDdType(t.getDdType());
                detailView.setDdName(t.getDdName());
                detailView.setDiscoveryId(t.getDiscoveryId());
                details.add(detailView);
                System.out.println("name-->"+t.getDdName()+"------type-------"+t.getDdType()+"-------------id--------------"+t.getDdConfigId()+"---------Metricname-----------"+t.getMetricName());
            
        
        res.setRecords(details);
        res.setPageNumber(page);
        if(limit != 0) 
            int Rem = (totalRecords%limit)>0?new Integer(1):0;
            int total = (int) (totalRecords/limit + Rem);
            res.setTotalPages(total);
            log.info("TotalRecords :"+totalRecords + "Total Pages:" +total);
                   
        return res;

   

当我在调试模式下检查时,执行不是只进入 for 循环,而是直接退出循环。

在控制台中执行休眠查询:

Hibernate: select tbidddetai0_.dd_metric_id as dd_metri1_34_, tbidddetai0_.dd_name as dd_name2_34_, tbidddetai0_.dd_type as dd_type3_34_, tbidddetai0_.discovery_id as discover4_34_, tbidddetai0_.key_words as key_word5_34_, tbidddetai0_.dd_metric_name as dd_metri6_34_ from tbi_datadiscovery_detail_view tbidddetai0_ cross join tbi_dd_config_master tbiddconfi1_ where tbidddetai0_.dd_metric_id=tbiddconfi1_.dd_metric_config_id and tbiddconfi1_.domain_id=? and (tbidddetai0_.dd_metric_name like ?) or tbiddconfi1_.keywords like ?
Hibernate: select tbiddconfi0_.dd_metric_config_id as dd_metri1_35_0_, tbiddconfi0_.created_by as created_2_35_0_, tbiddconfi0_.created_date as created_3_35_0_, tbiddconfi0_.domain_id as domain_i4_35_0_, tbiddconfi0_.is_active as is_activ5_35_0_, tbiddconfi0_.keywords as keywords6_35_0_, tbiddconfi0_.metric_name as metric_n7_35_0_, tbiddconfi0_.modified_by as modified8_35_0_, tbiddconfi0_.modified_date as modified9_35_0_ from tbi_dd_config_master tbiddconfi0_ where tbiddconfi0_.dd_metric_config_id=?
Hibernate: select tbidddetai0_.dd_metric_id as col_0_0_, tbidddetai0_.dd_metric_name as col_1_0_, tbidddetai0_.dd_type as col_2_0_, tbidddetai0_.dd_name as col_3_0_, tbidddetai0_.discovery_id as col_4_0_ from tbi_datadiscovery_detail_view tbidddetai0_ cross join tbi_dd_config_master tbiddconfi1_ where tbidddetai0_.dd_metric_id=tbiddconfi1_.dd_metric_config_id and tbidddetai0_.dd_metric_id=4926 and (upper(tbidddetai0_.dd_metric_name) like ?) limit ?
Hibernate: select tbidddetai0_.dd_metric_id as col_0_0_, tbidddetai0_.dd_metric_name as col_1_0_, tbidddetai0_.dd_type as col_2_0_, tbidddetai0_.dd_name as col_3_0_, tbidddetai0_.discovery_id as col_4_0_ from tbi_datadiscovery_detail_view tbidddetai0_ cross join tbi_dd_config_master tbiddconfi1_ where tbidddetai0_.dd_metric_id=tbiddconfi1_.dd_metric_config_id and tbidddetai0_.dd_metric_id=4926 and (upper(tbidddetai0_.dd_metric_name) like ?)
95953 [http-bio-9090-exec-3] INFO  com.acinfotech.timebound.jpa.service.ReportJobsPersistenceServiceImpl  - TotalRecords :0Total Pages:0

【问题讨论】:

【参考方案1】:

我已经通过将Creteria query 更改为Predicate 来实现它

检查以下对我有用的代码:

CriteriaBuilder cb=em.getCriteriaBuilder();
            CriteriaQuery<TbiDDDetailView> qry =cb.createQuery(TbiDDDetailView.class);
            Root root = qry.from(TbiDDDetailView.class);
            Root config = qry.from(TbiDDConfigMaster.class);

            List creteriaList = new ArrayList<>();
            Predicate predicate1 = cb.equal(root.get("tbiDDConfigMaster").get("ddConfigId"), config.get("ddConfigId"));
            creteriaList.add(predicate1);

            Predicate predicate2 = cb.equal(root.get("tbiDDConfigMaster").get("domainId"), domainId);
            creteriaList.add(predicate2);

            Predicate predicate3 = cb.or(cb.like(cb.upper(root.get("tbiDDConfigMaster").get("keywords")), "%"+searchString+"%"), cb.like(cb.upper(root.get("metricName")),"%"+searchString+"%"));

            CriteriaQuery<TbiDDDetailView> criteriaQuery = qry.select(cb.construct(TbiDDDetailView.class, root.get("ddConfigId"),root.get("metricName"),root.get("ddType"),
                    root.get("ddName"),root.get("discoveryId")));

            qry.where(cb.and((Predicate[]) creteriaList.toArray(new Predicate[0])), predicate3);  

TypedQuery<TbiDDDetailView> tq = em.createQuery(qry);  
return tq.getResultList();

【讨论】:

以上是关于通过 JPA 标准查询从 SQL 视图获取列表时出错的主要内容,如果未能解决你的问题,请参考以下文章

我可以从 JPA 查询对象中获取 SQL 字符串吗?

如何通过 Spring Boot JPA 执行具有 INTERVAL 子句的本机 SQL 查询?

sql server 创建视图添加表时出现从其他数据库导入的表未显示出来

如何在JAVA JPA Spring Boot中的一个SQL查询中选择多个数据

spring jpa查询视图

如何在本机查询中使用 NVL 或 COALESCE 获取 Spring Data JPA 中的值列表