现有实体和填充的DB值的JPA 2.0 IllegalArgumentException

时间:2015-09-25 15:26:59

标签: jpa

我正在尝试从已填充的表中基于条件ID(subid)从表中返回一个字符串。查询应返回ItemDataPoint类型实体的列表。在JSF托管bean中,列表将通过一个enhaned for循环进行迭代。如果单词" Include"通过循环找到,该方法将创建一个特定类型的图表。简单来说,我想根据满足的ID条件返回一个字符串。我得到了:

javax.ejb.EJBException
at com.sun.ejb.containers.EJBContainerTransactionManager.processSystemException
(EJBContainerTransactionManager.java:748)
at com.sun.ejb.containers.EJBContainerTransactionManager.
completeNewTx(EJBContainerTransactionManager.java:698)
at com.sun.ejb.containers.EJBContainerTransactionManager.postInvokeTx
(EJBContainerTransactionManager.java:503)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4475)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2009)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1979)
Caused by: java.lang.IllegalArgumentException: You have attempted to set 
a parameter at position 2 which does not exist in this query string SELECT p FROM 
Itemdatapoint p JOIN p.series s WHERE s.master.item.subs.subid = :subid.
at org.eclipse.persistence.internal.jpa.QueryImpl.setParameterInternal(QueryImpl.java:925)
at org.eclipse.persistence.internal.jpa.QueryImpl.setParameterInternal(QueryImpl.java:906)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.setParameter(EJBQueryImpl.java:469)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.setParameter(EJBQueryImpl.java:1)
at com.manaar.clientmods.gazprom.design3.data.facade.ItemdatapointFacade.
chartType(ItemdatapointFacade.java:78)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

如果我在数据库中的相关父表上运行本机SQL查询,则存在2的子值。此外,subid的类型是主实体类中的int,JPQL Facade类和托管bean。

JPQL:

public List<Itemdatapoint> chartType (int subid) {
    Query q = em.createQuery("SELECT p FROM Itemdatapoint p JOIN p.series s WHERE s.master.item.subs.subid = :subid");
    q.setParameter(subid, "subid");
    return q.getResultList();
}

托管bean:

@Named(value = "reportBean")
@SessionScoped
public class ReportBean implements Serializable {

@Inject
private ItemdatapointFacade facade;

public String typeSwitch1() {
    subid = 2;
   chartType = facade.chartType(subid);
   for(Itemdatapoint e: chartType) {
       status = e.getSeries().getMaster().getStatus();
       if(status.equals("Include")) {
           return "line";
       }
   }
   return null; 
}

xhtml页面:

<p:chart type="#{reportBean.typeSwitch1()}" model="#{reportBean.subLineChart1}"/>

我还尝试了从单个表中加入非JPQL:

public List<Itemdatapoint> noJoin (int subid) {
    Query q = em.createQuery("SELECT p FROM Itemdatapoint p WHERE p.pointid = :subid");
    q.setParameter(subid, "subid");
    return q.getResultList();

}

类似的问题:

 java.lang.IllegalArgumentException: You have attempted to set a
 parameter at position 2 which does not exist in this query string 
 SELECT p FROM Itemdatapoint p WHERE p.pointid = :subid.

我认为IllegalArgumentException意味着所选实体不存在或者不是与facade类中的查询字符串一致的正确类型。但在我的情况下,实体存在且参数是正确的类型。

如果我理解为什么会收到此错误,我将不胜感激。提前谢谢!

更新

回应lametaweb的回答,我想更好地理解JPA参数的概念。

根据JPA文档,setParameter方法的第一个参数是参数名称或编号。第二个参数是应该绑定到命名参数的对象。为什么以下工作没有抛出非法的ArgumentException?

我测试了一个xhtml(网页):

<p:dataGrid id="rep1" columns="1" value="#{pageBean.itemPageList1}"  var="items1" rows="4">
<p:commandLink value="#{items1.itemname}" action="#{pageBean.showItem1}" ajax="false"/>                                    
</p:dataGrid>

bean代码:

  public ListDataModel<Sectionitem> getItemPageList1() {
    subid = 1;
    reportStatus = "Include";
    itemPageList1 = itemFacade.viewItems(subid, reportStatus);
    return itemPageList1;
}

JPA门面:

public ListDataModel<Sectionitem> viewItems(int subid, String stat) {
    Query q = em.createQuery("select s from Sectionitem s JOIN s.subs c where c.subid = :subid AND s.status = :stat ORDER BY s.daterec");
 q.setParameter("subid", subid);
 q.setParameter("stat", stat);
    ListDataModel<Sectionitem> res
            = new ListDataModel<Sectionitem>(q.getResultList());
    return res;
}

为什么在这种情况下,对象存在,但在我原来的情况下,subid对象不存在?

1 个答案:

答案 0 :(得分:1)

您正在代码中调用此方法:

setParameter(int position, Object value)

但你必须改为调用这个:

setParameter(String name, Object value)

所以你的代码应该是:

q.setParameter("subid", Integer.valueOf(subid));

但是,如果你调用:

q.setParameter(subid, "subid");

这里第一个参数表示参数的位置,第二个参数表示它的值。所以你传递的是&#34; subid&#34;对于第二个(2)位置的参数,它不存在,因为您的JPQL查询中只有一个参数,因此IllegalArgumentException例外。

注意:为什么实体中有原始类型?为什么不是整数而不是int?