如何使用带有WHERE子句的抽象JPA?

时间:2013-07-12 19:31:29

标签: jpa

所以我有一个GeneralDao类和实现这个超类的类。

这是GeneralDao:

@Stateless
public abstract class GeneralDao<T> {

    @PersistenceContext(unitName = "Persistence")
    EntityManager em;

    public List<T> getAll(){
        TypedQuery<T> typedQuery = em.createQuery("Select t from " + getClassType().getSimpleName() + " t", getClassType());
        return typedQuery.getResultList();
    }


    public T getWithId(int id){
        TypedQuery<T> typedQuery = em.createQuery("Select t from " + getClassType().getSimpleName() + " t WHERE t." + getSimpleNameWithLowerFirstLetter() +"Id=id", getClassType());
        return typedQuery.getSingleResult();
    }

    private String getSimpleNameWithLowerFirstLetter(){
        String string = getClassType().getSimpleName();
        string = Character.toLowerCase(
                string.charAt(0)) + (string.length() > 1 ? string.substring(1) : "");
        return string;
    }

    protected abstract Class<T> getClassType();

}

这是一个扩展此类的示例类:

@Stateless
public class ActorDao extends GeneralDao<Actor> implements Serializable {

    @Override
    protected Class<Actor> getClassType() {
        return Actor.class;
    }

    @Override
    public Actor getWithId(int id){
        TypedQuery<Actor> typedQuery =
                em.createQuery("Select a From Actor a WHERE a.actorId =" + id,Actor.class);
        return typedQuery.getSingleResult();
    }    

}

现在的问题是,我可以使用

actorDao.getAll()

没有任何问题。请注意,此方法未被覆盖。

但是,如果我不重写

 actorDao.getWithId(int id)

我得到了:

java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Error compiling the query [Select t from Actor t WHERE t.actorId=id], line 1, column 38: unknown identification variable [id]. The FROM clause of the query does not declare an identification variable [id].

即使最终查询完全相同,如果没有覆盖,如此处所示,它将无效。

我错过了什么?

1 个答案:

答案 0 :(得分:4)

我会说你错过了原始查询中的冒号来标记占位符。此外,您应该使用形式参数为查询设置非常可变的变量,因此我们拥有:

尝试:

public T getWithId(int id){
    TypedQuery<T> typedQuery = em.createQuery("Select t from " + getClassType().getSimpleName() + " t WHERE t." + getSimpleNameWithLowerFirstLetter() +"Id= :id", getClassType());
    typedQuery.setParameter("id", id);
    return typedQuery.getSingleResult();
}

另请注意,getSingleResult()在绝对没有结果时会抛出exception,而getResultList()只会返回一个空列表。你可以安全地检查它是否为空。