【问题标题】:JPA criteria query load entire tableJPA 条件查询加载整个表
【发布时间】:2012-07-25 01:45:35
【问题描述】:

我觉得这是一个愚蠢的问题,但我找不到答案。我有一堂课如下:

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name="DEMO_VARIABLES")
public class Variable implements Serializable
{
    private static final long serialVersionUID = -1734898766626582592L;

    @Id
    @SequenceGenerator(name="VARIABLE_ID_GENERATOR", sequenceName="DEMO_VARIABLE_ID_SEQ", allocationSize=1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="VARIABLE_ID_GENERATOR")
    @Column(name="VARIABLE_ID", unique=true, nullable=false, precision=22)
    private long variableId;

    @Column(name="VARIABLE_NAME", nullable=false, length=50)
    private String variableName;

    @Column(name="VARIABLE_VALUE", nullable=false, length=500)
    private String variableValue;

    public Variable()
    {

    }

    public long getVariableId()
    {
        return variableId;
    }

    public void setVariableId(long variableId)
    {
        this.variableId = variableId;
    }

    public String getVariableName()
    {
        return variableName;
    }

    public void setVariableName(String variableName)
    {
        this.variableName = variableName;
    }

    public String getVariableValue()
    {
        return variableValue;
    }

    public void setVariableValue(String variableValue)
    {
        this.variableValue = variableValue;
    }
}

现在我想使用条件查询来加载整个表(即“从变量中选择 *”)。我想更多地使用标准查询来实现代码一致性,而不是其他任何东西。我得到了这个例外:

java.lang.IllegalStateException: No criteria query roots were specified
    at org.hibernate.ejb.criteria.CriteriaQueryImpl.validate(CriteriaQueryImpl.java:303)
    at org.hibernate.ejb.criteria.CriteriaQueryCompiler.compile(CriteriaQueryCompiler.java:145)
    at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:437

我使用的查询是:

public List<Variable> loadAllVariables()
{
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Variable> query = builder.createQuery(Variable.class);

    return em.createQuery(query).getResultList();
} 

我知道异常意味着它想要这个:

Root<Variable> variableRoot = query.from(Variable.class);

但是如果没有 Predicate,我看不到如何将 Root 对象放入查询中?

【问题讨论】:

    标签: jpa criteria-api


    【解决方案1】:

    我不确定,我是否理解正确,但如果目标是选择所有 Variable 实体的获取列表,那么以下是可行的方法:

    public List<Variable> loadAllVariables() {
        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<Variable> query = builder.createQuery(Variable.class);
        Root<Variable> variableRoot = query.from(Variable.class);
        query.select(variableRoot);
    
        return em.createQuery(query).getResultList();
    } 
    

    不同的是使用了select。所有实现都不会隐式使用最后一次调用 from 来代替 select。在 JPA 2.0 规范中,这被告知如下:

    便携式应用程序应使用选择或多选方法 指定查询的选择列表。不使用一个的应用程序 这些方法中的一些将不可移植。

    【讨论】:

    • 感谢工作。我只熟悉使用 query.where() 并基于 Root 给它一个 Predicated。 query.select() 是缺少的链接。
    【解决方案2】:

    使用查询及其根非常简单:
    首先按照您描述的方式获取根:

    Root<Variable> variableRoot = query.from(Variable.class);
    

    之后,您必须告诉查询它应该对根执行什么操作:在本例中为选择。

    query.select(variableRoot);
    

    之后,您可以使用query.where(...) 函数等进一步修改查询。 完成后,您就可以使用您的

    return em.createQuery(query).getResultList();
    

    更多信息the Oracle tutorial

    【讨论】:

      猜你喜欢
      • 2011-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多