【问题标题】:JPA NAMED Query issueJPA NAMED 查询问题
【发布时间】:2014-12-17 10:20:18
【问题描述】:

低于数据库异常,需要帮助

service() for servlet catalogservice threw exception: java.lang.IllegalArgumentException: Named query not found: SELECT OMX_PLAN_ID, PLAN_ID,DECODE(plan_id,0,ser_input_total_amount,first_payment) first_paymenmt From (SELECT OMX_PLAN_ID, PLAN_ID,(SELECT DECODE(fraction,0,fixed_payment_amount, (( fraction/100) * :useinput_total_amount)) From TFN.VW_OMX_PAYMENT_PLAN_DETAILS i WHERE o.OMX_PLAN_ID=i.OMX_PLAN_ID AND i.OMX_PLAN_ID=:omxPlanId AND i.PAYMENT_ID=1) first_payment FM TFN.VW_OMX_PAYMENT_PLANS o ) WHERE OMX_PLAN_ID=:omxPlanId ORDER by 1
        at org.hibernate.ejb.AbstractEntityManagerImpl.createNamedQuery(AbstractEntityManagerImpl.java:704) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Fin

DAO 方法

public TermPayment findFirstPaymentByTotalAndPlanId(int planId, double totalAmount) {

    TypedQuery<TermPayment> query = entityManager.createNamedQuery("SELECT OMX_PLAN_ID, PLAN_ID,DECODE(plan_id,0,:user_input_total_amount,first_payment) first_paymenmt From (SELECT OMX_PLAN_ID, PLAN_ID,(SELECT DECODE(fraction,0,fixed_payment_amount, (( fraction/100) * :user_input_total_amount)) From TFN.VW_OMX_PAYMENT_PLAN_DETAILS i WHERE o.OMX_PLAN_ID=i.OMX_PLAN_ID AND i.OMX_PLAN_ID=:omxPlanId AND i.PAYMENT_ID=1) first_payment FROM TFN.VW_OMX_PAYMENT_PLANS o ) WHERE OMX_PLAN_ID=:omxPlanId ORDER by 1", TermPayment.class);
    query.setParameter("omxPlanId", planId);
    query.setParameter("user_input_total_amount", totalAmount);
    return   query.getSingleResult();
}

返回类

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class TermPayment {
    @Id
    @Column(name = "OMX_PLAN_ID")   
    Integer omxPlanId;

    @Column(name = "PLAN_ID")   
    Integer planId;

    @Column(name = "FIRST_PAYMENT")
    Double firstPayment;

    public Integer getOmxPlanId() {
        return omxPlanId;
    }
    public void setOmxPlanId(Integer omxPlanId) {
        this.omxPlanId = omxPlanId;
    }
    public Integer getPlanId() {
        return planId;
    }
    public void setPlanId(Integer planId) {
        this.planId = planId;
    }
    public Double getFirstPayment() {
        return firstPayment;
    }
    public void setFirstPayment(Double firstPayment) {
        this.firstPayment = firstPayment;
    }
}

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    来自java.persistence.EntityManagerjavadoc:

    /**
     * Create an instance of <code>Query</code> for executing a named query
     * (in the Java Persistence query language or in native SQL).
     * @param name the name of a query defined in metadata
     * @return the new query instance
     * @throws IllegalArgumentException if a query has not been
     *         defined with the given name or if the query string is
     *         found to be invalid
     */
    public Query createNamedQuery(String name);
    

    所以你应该创建你的命名查询并且只使用createNamedQuery来引用它。

    【讨论】:

    • 有两种方法 Query createNamedQuery(java.lang.String name) TypedQuery createNamedQuery(java.lang.String name, java.lang.Class resultClass)跨度>
    • 我明白了,那你为什么不坚持各自的 javadoc 呢? "The select list of the query must contain only a single item, which must be assignable to the type specified by the &lt;code&gt;resultClass&lt;/code&gt; argument."
    【解决方案2】:

    如果要从字符串创建查询,可以使用 createQuery(String query, Class type) 方法。

    您可以替换 DAO 中使用的方法:

    entityManager.createNamedQuery(...)
    

    对于这个:

    entityManager.createQuery("select OMX_PLAN_ID, PLAN_ID ...", TermPayment.class)
    

    或者,您可以创建 NamedQuery,在 Entity 类中添加 NamedQuery 注释或使用 xml。之后,您可以使用 NamedQuery 将 NamedQuery 名称传递给 createNamedQuery() 方法。

    @NamedQuery(name="MyQuery", query="select OMX_PLAN_ID, PLAN_ID ...")
    
    entityManager.createNamedQuery(MyQuery, TermPayment.class);
    

    【讨论】:

      【解决方案3】:

      您正在尝试使用 NamedQuery api 来创建 dynamic queries 这是错误的。 来自doc

      createNamedQuery method is used to create static queries, or queries that are defined in metadata by using the javax.persistence.NamedQuery annotation. The name element of @NamedQuery specifies the name of the query that will be used with the createNamedQuery method. The query element of @NamedQuery is the query:

      @NamedQuery(
          name="findAllCustomersWithName",
          query="SELECT c FROM Customer c WHERE c.name LIKE :custName"
      )
      
      Here’s an example of createNamedQuery, which uses the @NamedQuery:
      
      @PersistenceContext
      public EntityManager em;
      ...
      customers = em.createNamedQuery("findAllCustomersWithName")
          .setParameter("custName", "Smith")
          .getResultList();
      

      你需要做一些类似的事情,

      entityManager.createQuery( "SELECT c FROM Customer c WHERE c.name LIKE :custName") .setParameter("custName", name)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-25
        • 2011-02-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多