通过 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 视图获取列表时出错的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 Spring Boot JPA 执行具有 INTERVAL 子句的本机 SQL 查询?
sql server 创建视图添加表时出现从其他数据库导入的表未显示出来