Fulltext Search: @Enumerated
mydeadlyvenoms opened this issue · comments
I reworked my model and tried some new use-cases.
I found out that it is currently not possible to search within enums if they are declared like below:
@Enumerated
@Column(columnDefinition = "smallint")
private Role role;
Since the Enums are being mapped to Integers, one needs to search for a particular Integer.
Of course a workaround would be to store the Enum as String.
Fixed in omnifaces/omnipersistence@79c6372
I just tried your fix, the following exception occured.
Local Exception Stack:
Exception [EclipseLink-6168] (Eclipse Persistence Services - 2.6.4.qualifier): org.eclipse.persistence.exceptions.QueryException
Exception Description: Query failed to prepare, unexpected error occurred: [java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Enum].
Internal Exception: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Enum
Query: ReadAllQuery(referenceClass=User )
at org.eclipse.persistence.exceptions.QueryException.prepareFailed(QueryException.java:1596)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:685)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.checkPrepare(ObjectLevelReadQuery.java:911)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:615)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:872)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1134)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:460)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1222)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1857)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1839)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258)
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:473)
at org.omnifaces.persistence.service.BaseEntityService.executeQuery(BaseEntityService.java:945)
at org.omnifaces.persistence.service.BaseEntityService.getPage(BaseEntityService.java:877)
at org.omnifaces.persistence.service.BaseEntityService.getPage(BaseEntityService.java:790)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
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:4836)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:836)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:64)
at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52)
at sun.reflect.GeneratedMethodAccessor62.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:835)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
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.GeneratedMethodAccessor64.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:895)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:835)
at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:374)
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4808)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4796)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:90)
at com.sun.proxy.$Proxy462.getPage(Unknown Source)
at ... __Intf____Bean__.getPage(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.weld.util.reflection.Reflections.invokeAndUnwrap(Reflections.java:433)
at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:127)
at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56)
at org.jboss.weld.bean.proxy.InjectionPointPropagatingEnterpriseTargetBeanInstance.invoke(InjectionPointPropagatingEnterpriseTargetBeanInstance.java:67)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:100)
...
at org.omnifaces.optimusfaces.model.LazyPagedDataModel.load(LazyPagedDataModel.java:159)
at org.omnifaces.optimusfaces.model.LazyPagedDataModel.loadPage(LazyPagedDataModel.java:143)
at org.omnifaces.optimusfaces.model.LazyPagedDataModel.load(LazyPagedDataModel.java:134)
at org.primefaces.component.datatable.DataTable.loadLazyData(DataTable.java:1116)
at org.primefaces.component.datatable.feature.FilterFeature.encode(FilterFeature.java:120)
at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:85)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:920)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1863)
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:582)
at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
at org.primefaces.component.api.UIData.visitTree(UIData.java:827)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIForm.visitTree(UIForm.java:371)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:403)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:322)
at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:57)
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:219)
at org.omnifaces.context.OmniPartialViewContext.processPartial(OmniPartialViewContext.java:124)
at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:1004)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:432)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:134)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at org.omnifaces.viewhandler.OmniViewHandler.renderView(OmniViewHandler.java:119)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:659)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1692)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:339)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:209)
at org.omnifaces.filter.FacesExceptionFilter.doFilter(FacesExceptionFilter.java:97)
at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:251)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:209)
at org.glassfish.tyrus.servlet.TyrusServletFilter.doFilter(TyrusServletFilter.java:305)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:251)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:209)
at ... .SecurityHeaderHttpFilter.doFilter(SecurityHeaderHttpFilter.java:51)
at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:251)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:209)
at org.omnifaces.filter.GzipResponseFilter.doFilter(GzipResponseFilter.java:181)
at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:251)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:209)
at org.omnifaces.facesviews.FacesViewsForwardingFilter.filterExtensionLessToExtension(FacesViewsForwardingFilter.java:184)
at org.omnifaces.facesviews.FacesViewsForwardingFilter.filterExtensionLess(FacesViewsForwardingFilter.java:141)
at org.omnifaces.facesviews.FacesViewsForwardingFilter.filterExtensionLess(FacesViewsForwardingFilter.java:127)
at org.omnifaces.facesviews.FacesViewsForwardingFilter.doFilter(FacesViewsForwardingFilter.java:88)
at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:251)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:209)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:654)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:593)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:159)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:483)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:180)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Enum
at org.eclipse.persistence.mappings.converters.EnumTypeConverter.convertObjectValueToDataValue(EnumTypeConverter.java:160)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.getFieldValue(AbstractDirectMapping.java:778)
at org.eclipse.persistence.internal.expressions.QueryKeyExpression.getFieldValue(QueryKeyExpression.java:420)
at org.eclipse.persistence.internal.expressions.QueryKeyExpression.getFieldValue(QueryKeyExpression.java:413)
at org.eclipse.persistence.internal.expressions.CollectionExpression.printSQL(CollectionExpression.java:36)
at org.eclipse.persistence.expressions.ExpressionOperator.printDuo(ExpressionOperator.java:2239)
at org.eclipse.persistence.internal.expressions.CompoundExpression.printSQL(CompoundExpression.java:286)
at org.eclipse.persistence.internal.expressions.RelationExpression.printSQL(RelationExpression.java:899)
at org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter.translateExpression(ExpressionSQLPrinter.java:325)
at org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter.printExpression(ExpressionSQLPrinter.java:129)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.printSQL(SQLSelectStatement.java:1755)
at org.eclipse.persistence.platform.database.MySQLPlatform.printSQLSelectStatement(MySQLPlatform.java:735)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:843)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:854)
at org.eclipse.persistence.descriptors.ClassDescriptor.buildCallFromStatement(ClassDescriptor.java:815)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.setCallFromStatement(StatementQueryMechanism.java:390)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.prepareSelectAllRows(StatementQueryMechanism.java:315)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.prepareSelectAllRows(ExpressionQueryMechanism.java:1723)
at org.eclipse.persistence.queries.ReadAllQuery.prepareSelectAllRows(ReadAllQuery.java:885)
at org.eclipse.persistence.queries.ReadAllQuery.prepare(ReadAllQuery.java:816)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:666)
... 142 more
]]
Works on Hibernate. It looks like that EclipseLink doesn't support specifying ordinals in the query. I'll fix this other day and add an IT.
I guess this (supporting all the various implementations) is one of the hardest parts when writing such a utility library.
At least I can contribute passively by testing all the features. :-)
Almost all ITs have passed, only Payara+EclipseLink+PostgreSQL has trouble with sorting as it seems to sort by enum ordinal instead of by enum string:
Failed tests:
OptimusFacesPostgreSQLIT>OptimusFacesIT.testLazyPagingSortingAndFiltering:465->OptimusFacesIT.testPagingSortingAndFiltering:707->OptimusFacesIT.assertSortedState:1240 gender ordering expected:<[FEMALE, FEMALE, MALE, MALE, MALE, MALE, MALE, MALE, MALE, MALE]> but was:<[MALE, MALE, MALE, MALE, MALE, MALE, MALE, MALE, FEMALE, FEMALE]>
OptimusFacesPostgreSQLIT>OptimusFacesIT.testNonLazyPagingSortingAndFiltering:471->OptimusFacesIT.testPagingSortingAndFiltering:707->OptimusFacesIT.assertSortedState:1240 gender ordering expected:<[FEMALE, FEMALE, MALE, MALE, MALE, MALE, MALE, MALE, MALE, MALE]> but was:<[MALE, MALE, MALE, MALE, MALE, MALE, MALE, MALE, FEMALE, FEMALE]>
Will look into this later, but for now the filtering should work for you.
You are right, the implemented solution works for me.
Thank you!
I didn't fix sorting as this is just a technical limitation. Either enum values should be manually ordered in the enum class itself, or values should be saved as string instead of as ordinal in DB.
In my case sorting works. Anyway, thank you for the fix!