Hibernate JPA中带ON条件的外连接

Hibernate JPA中带ON条件的外连接,hibernate,jpa,eclipselink,criteria,jpa-2.1,Hibernate,Jpa,Eclipselink,Criteria,Jpa 2.1,我需要以下SQL查询的条件查询 选择w.weight\u id、w.weight、zc.charge 从重量w 左外连接区w.weight\u id=zc.weight\u id上的电荷zc 和zc.zone_id= with操作符是JPQL的特定于hibernate的扩展。在criteria API中找不到对它的支持。这可以与使用新功能提供的criteria API一起完成。因此,问题中给出的条件查询可以重写如下 CriteriaBuilder criteriaBuilder=entityMa

我需要以下SQL查询的条件查询

选择w.weight\u id、w.weight、zc.charge
从重量w
左外连接区w.weight\u id=zc.weight\u id上的电荷zc

和zc.zone_id=
with
操作符是JPQL的特定于hibernate的扩展。在criteria API中找不到对它的支持。

这可以与使用新功能提供的criteria API一起完成。因此,问题中给出的条件查询可以重写如下

CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery<Tuple>criteriaQuery=criteriaBuilder.createQuery(Tuple.class);
Root<Weight> root = criteriaQuery.from(entityManager.getMetamodel().entity(Weight.class));

ListJoin<Weight, ZoneCharge> join = root.join(Weight_.zoneChargeList, JoinType.LEFT);
criteriaQuery.multiselect(root.get(Weight_.weightId), root.get(Weight_.weight), join.get(ZoneCharge_.charge));

ParameterExpression<Long>parameterExpression=criteriaBuilder.parameter(Long.class);
join.on(criteriaBuilder.equal(join.get(ZoneCharge_.zoneTable).get(ZoneTable_.zoneId), parameterExpression));

criteriaQuery.orderBy(criteriaBuilder.asc(root.get(Weight_.weight)));
List<Tuple> list = entityManager.createQuery(criteriaQuery).setParameter(parameterExpression, 1L).getResultList();
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery<Tuple>criteriaQuery=criteriaBuilder.createQuery(Tuple.class);
Root<Weight> root = criteriaQuery.from(entityManager.getMetamodel().entity(Weight.class));

ListJoin<Weight, ZoneCharge> join = root.join(Weight_.zoneChargeList, JoinType.LEFT);

criteriaQuery.multiselect(root.get(Weight_.weightId), root.get(Weight_.weight), join.get(ZoneCharge_.charge));
join.on(criteriaBuilder.equal(join.get(ZoneCharge_.zoneTable).get(ZoneTable_.zoneId), 1L));

criteriaQuery.orderBy(criteriaBuilder.asc(root.get(Weight_.weight)));
List<Tuple> list = entityManager.createQuery(criteriaQuery).getResultList();
值得一提的是,此查询在Hibernate()上成功,但在EclipseLink()上意外失败,出现以下异常

java.lang.IllegalArgumentException: No parameter with name : Parameter[name=null] was found within the query: ReportQuery(referenceClass=Weight ).
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.setParameter(EJBQueryImpl.java:548)
    at admin.beans.ZoneChargeBean.getZoneChargeList(ZoneChargeBean.java:83)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
    at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
    at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4695)
    at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:630)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:582)
    at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:46)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:582)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:140)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
    at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:369)
    at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4667)
    at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4655)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
    ... 72 more
parametexpression
必须删除才能按如下方式工作

CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery<Tuple>criteriaQuery=criteriaBuilder.createQuery(Tuple.class);
Root<Weight> root = criteriaQuery.from(entityManager.getMetamodel().entity(Weight.class));

ListJoin<Weight, ZoneCharge> join = root.join(Weight_.zoneChargeList, JoinType.LEFT);
criteriaQuery.multiselect(root.get(Weight_.weightId), root.get(Weight_.weight), join.get(ZoneCharge_.charge));

ParameterExpression<Long>parameterExpression=criteriaBuilder.parameter(Long.class);
join.on(criteriaBuilder.equal(join.get(ZoneCharge_.zoneTable).get(ZoneTable_.zoneId), parameterExpression));

criteriaQuery.orderBy(criteriaBuilder.asc(root.get(Weight_.weight)));
List<Tuple> list = entityManager.createQuery(criteriaQuery).setParameter(parameterExpression, 1L).getResultList();
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery<Tuple>criteriaQuery=criteriaBuilder.createQuery(Tuple.class);
Root<Weight> root = criteriaQuery.from(entityManager.getMetamodel().entity(Weight.class));

ListJoin<Weight, ZoneCharge> join = root.join(Weight_.zoneChargeList, JoinType.LEFT);

criteriaQuery.multiselect(root.get(Weight_.weightId), root.get(Weight_.weight), join.get(ZoneCharge_.charge));
join.on(criteriaBuilder.equal(join.get(ZoneCharge_.zoneTable).get(ZoneTable_.zoneId), 1L));

criteriaQuery.orderBy(criteriaBuilder.asc(root.get(Weight_.weight)));
List<Tuple> list = entityManager.createQuery(criteriaQuery).getResultList();
CriteriaBuilder-CriteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuerycriteriaQuery=criteriaBuilder.createQuery(Tuple.class);
Root=criteriaQuery.from(entityManager.getMetamodel().entity(Weight.class));
ListJoin=root.join(Weight.zoneChargeList,JoinType.LEFT);
multiselect(root.get(Weight.weightId)、root.get(Weight.Weight)、join.get(ZoneCharge.charge));
join.on(criteriaBuilder.equal(join.get(ZoneCharge_u.zoneTable).get(zoneTable_u.zoneId),1L));
criteriaQuery.orderBy(criteriaBuilder.asc(root.get(Weight.Weight));
List List=entityManager.createQuery(criteriaQuery.getResultList();

这应该是EclipseLink 2.5.1中的一个疏忽。

因此,我必须只使用JPQL?是的,HQL实际上,因为
with
不是JPQL关键字。它是否受Hibernate标准的支持?这个查询将是动态的,顺便说一下,通过字符串连接构造查询有点乏味。@Tiny我想知道如果使用JPQL而不是createQuery,将如何处理过滤条件?例如,如果我的DAOImpl方法接收到任何过滤条件,并且如果我想将其作为过滤条件的参数传递给JPQL,那么我的查询应该是
like%
可能会有性能问题,不是吗?