【问题标题】:Calling a MySql routine/stored procedure with an EJB Query使用 EJB 查询调用 MySql 例程/存储过程
【发布时间】:2012-05-15 09:39:45
【问题描述】:

经过一番折腾,我的 webapp 已经接近最终版本了,但它仍然需要一些东西。

所以我需要使用“复杂”查询来获取一些结果。

此查询需要调用 MySql 例程,并且必须返回 Map 而不是 List

这是查询:

SELECT d.id, contaOccorrenze(d.descrizione, '" + query + "') AS 'occorrenze' FROM Dispensa d WHERE d.tag LIKE '%" + query + "%' OR d.titolo LIKE '%" + query + "%' OR d.descrizione LIKE '%" + query + "%'

query 是我要查找的词,contaOccorrenze 是我需要调用的例程。

这个查询在 Workbench 中运行良好,所以这个查询不是我的问题。

这是我尝试执行查询后出现的堆栈跟踪:

    Caused by: java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Syntax error parsing the query [SELECT d.id, contaOccorrenze(d.descrizione, 'lunga') AS 'occorrenze' FROM Dispensa d WHERE d.tag LIKE '%lunga%' OR d.titolo LIKE '%lunga%' OR d.descrizione LIKE '%lunga%'], line 1, column 28: unexpected token [(].
Internal Exception: NoViableAltException(83@[()* loopback of 383:9: (d= DOT right= attribute )*])
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1477)
    at com.sun.enterprise.container.common.impl.EntityManagerWrapper.createQuery(EntityManagerWrapper.java:436)
    at facade.DispensaFacade.findLikeComplex(DispensaFacade.java:101)
    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 com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
    at sun.reflect.GeneratedMethodAccessor80.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)
    ... 77 more
Caused by: Exception [EclipseLink-8025] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.JPQLException
Exception Description: Syntax error parsing the query [SELECT d.id, contaOccorrenze(d.descrizione, 'lunga') AS 'occorrenze' FROM Dispensa d WHERE d.tag LIKE '%lunga%' OR d.titolo LIKE '%lunga%' OR d.descrizione LIKE '%lunga%'], line 1, column 28: unexpected token [(].
Internal Exception: NoViableAltException(83@[()* loopback of 383:9: (d= DOT right= attribute )*])
    at org.eclipse.persistence.exceptions.JPQLException.unexpectedToken(JPQLException.java:372)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.handleRecognitionException(JPQLParser.java:320)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.addError(JPQLParser.java:246)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.reportError(JPQLParser.java:363)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.pathExprOrVariableAccess(JPQLParser.java:1436)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.arithmeticPrimary(JPQLParser.java:4720)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.arithmeticFactor(JPQLParser.java:4660)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.arithmeticTerm(JPQLParser.java:4546)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.simpleArithmeticExpression(JPQLParser.java:4462)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.scalarExpression(JPQLParser.java:4834)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.selectExpression(JPQLParser.java:1269)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.selectItem(JPQLParser.java:1169)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.selectClause(JPQLParser.java:1108)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.selectStatement(JPQLParser.java:359)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.document(JPQLParser.java:281)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.parse(JPQLParser.java:134)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.buildParseTree(JPQLParser.java:95)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:215)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:190)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:142)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:126)
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1475)
    ... 100 more
Caused by: NoViableAltException(83@[()* loopback of 383:9: (d= DOT right= attribute )*])
    at org.eclipse.persistence.internal.libraries.antlr.runtime.DFA.noViableAlt(DFA.java:159)
    at org.eclipse.persistence.internal.libraries.antlr.runtime.DFA.predict(DFA.java:116)
    at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.pathExprOrVariableAccess(JPQLParser.java:1408)
    ... 117 more

这是我尝试使用的完整方法(将结果 List 转换为 HashMap 是我在谷歌上发现的一种方式,但我很确定有更好的方法来获取 @987654329 @来自我的查询)

public HashMap<Integer, Integer> findLikeComplex(String query) {
        String SQLquery = "SELECT d.id, contaOccorrenze(d.descrizione, '" + query + "') AS 'occorrenze' FROM Dispensa d WHERE d.tag LIKE '%" + query + "%' OR d.titolo LIKE '%" + query + "%' OR d.descrizione LIKE '%" + query + "%'";
        return (HashMap<Integer, Integer>) getEntityManager().createQuery(SQLquery).getResultList();        
    }

我还想通过将查询的d.id 语句更改为*,将我的HashMapHashMap&lt;Integer, Integer&gt; 更改为HashMap&lt;Dispensa, Integer&gt;

它会起作用还是我要求太多了?

【问题讨论】:

    标签: mysql stored-procedures ejb entitymanager


    【解决方案1】:

    你应该试试getEntityManager().createNativeQuery()

    【讨论】:

    • 它有效。我的意思是,它会进行查询,但会抛出一个异常,指出不能将 Vector 强制转换为 HashMap(这很明显)。如何使此查询返回 Map 而不是 List
    • Afaik 你不能。所以你必须遍历结果并将它们添加到你的地图..
    • 已解决。 getResultList() 在这种情况下返回 List&lt;Object[]&gt; :)
    猜你喜欢
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    • 2012-06-15
    • 1970-01-01
    • 2012-06-24
    相关资源
    最近更新 更多