[英]JPA Criteria API persistent field IN expression using list of entities
I'm trying something similar to this question posted before: 我正在尝试类似于之前发布的问题:
JPA Criteria API IN expression Parameter list JPA Criteria API IN表达式参数列表
However, I'm trying to use a list of entities instead of a list of Longs (PKs), like: 但是,我尝试使用实体列表而不是Longs(PK)列表,例如:
public List<Task> generateFilteredQuery( List<User> filterUsers )
{
CriteriaBuilder cb = this.em.getCriteriaBuilder();
CriteriaQuery<Task> criteriaQuery = cb.createQuery( Task.class );
Root<Task> root = criteriaQuery.from( Task.class );
criteriaQuery.select( root ).where( root.get( "owner" ).in( filterUsers ) );
return this.em.createQuery( criteriaQuery ).getResultList();
}
Please assume this.em
to be of type EntityManager
. 请假定this.em
为EntityManager
类型。 The Task
entity has an associated owner, mapped like this: Task
实体具有关联的所有者,其映射如下:
@Entity
@Table( name = "TASKS" )
public class Task implements Serializable
{
...
@ManyToOne( fetch = FetchType.EAGER )
@JoinColumn( name = "OWNER_USER_ID", referencedColumnName = "USER_ID" )
private User owner;
...
}
I know I have used something similar from JPQL before, but I don't see how it is done using the Criteria API. 我知道我以前使用过与JPQL类似的东西,但是我看不到使用Criteria API是如何完成的。
Using the above code causes a DB exception to ocurr: 使用上面的代码会导致发生数据库异常:
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.microsoft.sqlserver.jdbc.SQLServerException: Fehler beim Konvertieren des nvarchar-Datentyps in bigint.
Error Code: 8114
Call: SELECT DISTINCT t1.TASK_ID, t1.CLIENT_ID, t1.CLOSE_TIME, t1.CLOSE_USER_ID, t1.TASK_DATE, t1.TASK_DATE_ID, t1.LASTACTION, t1.LASTHOST_ID, t1.LASTTIME, t1.LASTUSER_ID, t1.OBJECT_ID, t1.OWNER_USER_ID, t1.STATUS_TEXT, t1.STATUS, t1.TABLE_ID, t1.TASK_TRIGGER_ID, t1.TASK_TYPE FROM TASKS t1 LEFT OUTER JOIN TASK_TYPES t2 ON (t2.TASK_TYPE_ID = t1.TASK_TYPE) LEFT OUTER JOIN TASK_TRIGGERS t3 ON (t3.TASK_TRIGGER_ID = t1.TASK_TRIGGER_ID) LEFT OUTER JOIN USERS t4 ON (t4.USER_ID = t1.LASTUSER_ID) LEFT OUTER JOIN USERS t5 ON (t5.USER_ID = t1.CLOSE_USER_ID), USERS t0 WHERE ((((t1.CLIENT_ID = ?) AND ((((((LOWER(t2.NAME) LIKE ? OR LOWER(t1.STATUS) LIKE ?) OR LOWER(t1.STATUS_TEXT) LIKE ?) OR LOWER(t0.USER_NAME) LIKE ?) OR LOWER(t3.DESCRIPTION) LIKE ?) OR LOWER(t4.USER_NAME) LIKE ?) OR LOWER(t5.USER_NAME) LIKE ?)) AND (t1.OWNER_USER_ID IN (?))) AND (t0.USER_ID = t1.OWNER_USER_ID)) ORDER BY t1.LASTTIME DESC
bind => [1, %%, %%, %%, %%, %%, %%, %%, User [id=437, getUserName()=bla, clients=[], .................]]
Query: ReadAllQuery(referenceClass=Task sql="SELECT DISTINCT t1.TASK_ID, t1.CLIENT_ID, t1.CLOSE_TIME, t1.CLOSE_USER_ID, t1.TASK_DATE, t1.TASK_DATE_ID, t1.LASTACTION, t1.LASTHOST_ID, t1.LASTTIME, t1.LASTUSER_ID, t1.OBJECT_ID, t1.OWNER_USER_ID, t1.STATUS_TEXT, t1.STATUS, t1.TABLE_ID, t1.TASK_TRIGGER_ID, t1.TASK_TYPE FROM TASKS t1 LEFT OUTER JOIN TASK_TYPES t2 ON (t2.TASK_TYPE_ID = t1.TASK_TYPE) LEFT OUTER JOIN TASK_TRIGGERS t3 ON (t3.TASK_TRIGGER_ID = t1.TASK_TRIGGER_ID) LEFT OUTER JOIN USERS t4 ON (t4.USER_ID = t1.LASTUSER_ID) LEFT OUTER JOIN USERS t5 ON (t5.USER_ID = t1.CLOSE_USER_ID), USERS t0 WHERE ((((t1.CLIENT_ID = ?) AND ((((((LOWER(t2.NAME) LIKE ? OR LOWER(t1.STATUS) LIKE ?) OR LOWER(t1.STATUS_TEXT) LIKE ?) OR LOWER(t0.USER_NAME) LIKE ?) OR LOWER(t3.DESCRIPTION) LIKE ?) OR LOWER(t4.USER_NAME) LIKE ?) OR LOWER(t5.USER_NAME) LIKE ?)) AND (t1.OWNER_USER_ID IN (?))) AND (t0.USER_ID = t1.OWNER_USER_ID)) ORDER BY t1.LASTTIME DESC")
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:646)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:537)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1800)
at org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:566)
at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:240)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:207)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:193)
at org.eclipse.persistence.internal.
INFO: queries.DatasourceCallQueryMechanism.executeSelectCall(DatasourceCallQueryMechanism.java:264)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.selectAllRows(DatasourceCallQueryMechanism.java:648)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRowsFromTable(ExpressionQueryMechanism.java:2706)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRows(ExpressionQueryMechanism.java:2659)
at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:421)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1150)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:852)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1109)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:393)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1197)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2875)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1602)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1584)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1549)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:231)
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:411)
at com.sun.enterprise.container.common.impl.QueryWrapper.getResultList(QueryWrapper.java:195)
at com.sun.enterprise.container.common.impl.TypedQueryWrapper.getResultList(TypedQueryWrapper.java:129)
at de.bnext.core.base.repository.BaseEntityRepositoryBean.findBy(BaseEntityRepositoryBean.java:448)
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:1052)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
at de.bnext.core.interceptor.persistence.PersistencePropertiesInterceptor.injectPersistenceProperties(PersistencePropertiesInterceptor.java:81)
at sun.reflect.GeneratedMethodAccessor1084.invoke(Unknown Source)
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:861)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
at de.bnext.core.interceptor.common.NullCheckInterceptor.checkNull(NullCheckInterceptor.java:85)
at sun.reflect.GeneratedMethodAccessor1083.invoke(Unknown Source)
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:861)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
at de.bnext.core.interceptor.logging.LoggingInterceptor.logMethod(LoggingInterceptor.java:90)
at sun.reflect.GeneratedMethodAccessor1078.invoke(Unknown Source)
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:861)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:42)
at sun.reflect.GeneratedMethodAccessor1077.invoke(Unknown Source)
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:861)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
at sun.reflect.GeneratedMethodAccessor1076.invoke(Unknown Source)
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:861)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370)
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214)
... 120 more
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Fehler beim Konvertieren des nvarchar-Datentyps in bigint.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet$FetchBuffer.nextRow(SQLServerResultSet.java:4853)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.fetchBufferNext(SQLServerResultSet.java:1781)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.next(SQLServerResultSet.java:1034)
at com.sun.gjc.spi.base.ResultSetWrapper.next(ResultSetWrapper.java:103)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processResultSet(DatabaseAccessor.java:715)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:623)
... 194 more
The problem with this basically is the part ... AND (t1.OWNER_USER_ID IN (?))) ...
as this assumes some kind of List to be used. 基本上,问题在于... AND (t1.OWNER_USER_ID IN (?))) ...
这部分假定要使用某种列表。 This is not desired. 这是不希望的。
I remember having done something like that with JPQL and Hibernate as a JPA provider before, now here's the question. 我记得以前曾与JPQL和Hibernate作为JPA提供者一起做过类似的事情,现在是问题所在。
Q : 问 :
Is there a Criteria equivalent for JPQL ... WHERE task.owner IN :filterUsers
, where :filterUsers
is a standard named paramater using query.setParameter( "filterUsers", filterUsers )
and the latter being declared as List<User> filterUsers = ...
? 是否有与JPQL ... WHERE task.owner IN :filterUsers
相同的条件... WHERE task.owner IN :filterUsers
,其中:filterUsers
是使用query.setParameter( "filterUsers", filterUsers )
命名为:filterUsers
的标准query.setParameter( "filterUsers", filterUsers )
后者被声明为List<User> filterUsers = ...
? If so, how's it done? 如果是这样,怎么做?
PS: Sorry for the German error messages, I really h*te localized error messages (and I can't repeat that too many times!). PS:抱歉,德语错误消息,我确实是本地化的错误消息(我不能重复太多次了!)。
You can try this, 你可以试试看
Criteria criteria = getSession().createCriteria(Task .class);
criteria.createAlias("owner.id", "filterUsers");
criteria.add(Restrictions.in("filterUsers", <List that contains user ids>));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.