1

所以我有一个 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].

即使最终的查询完全相同,如果没有像这里看到的那样被覆盖,它将无法工作。

我错过了什么?

4

1 回答 1

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()会引发异常getResultList(),而只会返回一个空列表。您可以安全地检查它是否为空。

于 2013-07-12T19:47:39.693 回答