1

以前に投稿されたこの質問に似たものを試しています:

JPA Criteria API IN 式 パラメータ リスト

ただし、次のように、Long (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();
}

this.em型であると仮定してくださいEntityManager。エンティティには、次の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;

        ...
}

以前にJPQLから同様のものを使用したことは知っていますが、Criteria APIを使用してそれがどのように行われるかわかりません.

上記のコードを使用すると、DB 例外が発生します。

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

これに関する問題は、基本的に、... AND (t1.OWNER_USER_ID IN (?))) ...ある種のリストが使用されることを前提としている部分です。これは望ましくありません。

JPAプロバイダーとしてJPQLとHibernateでそのようなことをしたことを覚えていますが、ここで質問です。

Q :

JPQL... WHERE task.owner IN :filterUsersに相当する Criteria:filterUsersはありquery.setParameter( "filterUsers", filterUsers )ますList<User> filterUsers = ...か? もしそうなら、それはどのように行われますか?

PS: ドイツ語のエラー メッセージで申し訳ありません。ローカライズされたエラー メッセージは本当に嫌いです (何度も繰り返すことはできません!)。

4

1 に答える 1