JPA / JPQL:如何使用hash-map的member-of

时间:2018-03-28 19:07:01

标签: jpql jql entity-bean

使用Statement-member时遇到问题。我认为的问题是,我在元素上犯了一个错误 - > parameter.get("" i + anlass)但我不知道该怎么做。 是否还有其他可能性来询问某个元素是否来自另一个对象的@ManyToMany列表?

这是我的代码:

   /*My Beans: 
    @Entity
    public class Rezept implements Serializable {
    ...........
    @ManyToMany(mappedBy="rezepten", cascade = {CascadeType.PERSIST})
     List<Allergie> allergien = new ArrayList<>();

    @ManyToMany(mappedBy="rezepten", cascade = {CascadeType.PERSIST})
     List<Anlass> anlässe = new ArrayList<>();

    @ManyToMany(mappedBy="rezepten", cascade = {CascadeType.PERSIST})
     List<Grundzutat> grundzutaten = new ArrayList<>();*/



//The method is in the RezeptBean
 public List<Rezept> searchByFilters(List<Anlass> anlaesse, List<Grundzutat> grundzutaten, List<Allergie> allergien) {
    // WHERE-Bedingungen für die Filteroptionen zusammenbauen
    String select = "SELECT r FROM Rezept r";
    String where = "";

    Map<String, Object> parameters = new HashMap<>();
    int i = 0;

    for (Anlass anlass : anlaesse) {
        i++;
        parameters.put("" + i, anlass);

        if (!where.isEmpty()) {
            where += " AND ";
        }
        //Here I want to see if the element parameters.get("" + i) is member 
         of r.anlässe
        where += ":" + parameters.get("" + i) + " MEMBER OF r.anlässe";
    }

    for (Grundzutat grundzutat : grundzutaten) {
        i++;
        parameters.put("" + i, grundzutat);

        if (!where.isEmpty()) {
            where += " AND ";
        }

        where += ":" + parameters.get("" + i) + " MEMBER OF r.grundzutaten";
    }

    for (Allergie allergie : allergien) {
        i++;
        parameters.put("" + i, allergie);

        if (!where.isEmpty()) {
            where += " AND ";
        }

        where += ":" + parameters.get("" + i) + " MEMBER OF r.allergien";
    }

    // Finalen SELECT-String zusammenbauen und Suche ausführen
    if (!where.isEmpty()) {
        select += " WHERE " + where;
    }

    Query query = em.createQuery(select);

    for (String key : parameters.keySet()) {
        query.setParameter(key, parameters.get(key));
    }

    return query.getResultList();
}


}

这是日志文件:

    Warnung:   A system exception occurred during an invocation on EJB RezeptBean, method: public java.util.List rezept.ejb.RezeptBean.searchByFilters(java.util.List,java.util.List,java.util.List)
Warnung:   javax.ejb.EJBException
    at com.sun.ejb.containers.EJBContainerTransactionManager.processSystemException(EJBContainerTransactionManager.java:752)
    at com.sun.ejb.containers.EJBContainerTransactionManager.completeNewTx(EJBContainerTransactionManager.java:702)
    at com.sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx(EJBContainerTransactionManager.java:507)
    at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4566)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2074)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2044)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:220)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
    at com.sun.proxy.$Proxy1243.searchByFilters(Unknown Source)
    at rezept.ejb.__EJB31_Generated__RezeptBean__Intf____Bean__.searchByFilters(Unknown Source)
    at rezept.web.SuchServlet.doGet(SuchServlet.java:125)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at rezept.web.JavaFilter.doFilter(JavaFilter.java:48)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    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:283)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
    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:591)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Syntax error parsing [SELECT r FROM Rezept r WHERE :rezept.jpa.Anlass@2c9e9a75 MEMBER OF r.anlässe AND :rezept.jpa.Grundzutat@3c634785 MEMBER OF r.grundzutaten AND :rezept.jpa.Grundzutat@3c30782 MEMBER OF r.grundzutaten AND :rezept.jpa.Allergie@4f608eda MEMBER OF r.allergien AND :rezept.jpa.Allergie@1482f49f MEMBER OF r.allergien]. 
[29, 56] The named input parameter ''{0}'' is not following the rules for a Java identifier.
[81, 112] The named input parameter ''{0}'' is not following the rules for a Java identifier.
[142, 172] The named input parameter ''{0}'' is not following the rules for a Java identifier.
[202, 231] The named input parameter ''{0}'' is not following the rules for a Java identifier.
[258, 287] The named input parameter ''{0}'' is not following the rules for a Java identifier.
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1616)
....................

有人知道我能做些什么不同吗?

1 个答案:

答案 0 :(得分:0)

您不必将WHERE子句中的列名前缀为:,它仅用于参数值。

堆栈跟踪中的查询显示查询中:的使用情况:

SELECT r FROM Rezept r 
WHERE :rezept.jpa.Anlass@2c9e9a75 MEMBER OF r.anlässe AND
      :rezept.jpa.Grundzutat@3c634785 MEMBER OF r.grundzutaten AND 
      :rezept.jpa.Grundzutat@3c30782 MEMBER OF r.grundzutaten AND 
      :rezept.jpa.Allergie@4f608eda MEMBER OF r.allergien AND 
      :rezept.jpa.Allergie@1482f49f MEMBER OF r.allergien

这可以在您的Java代码中更正如下(将以下行更改为如图所示,而不使用:来解决问题:

改变这个:

where += ":" + parameters.get("" + i) + " MEMBER OF r.anlässe";

到此:

where += parameters.get("" + i) + " MEMBER OF r.anlässe";

希望这有助于@Alina!