所以我有一个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].
即使最终查询完全相同,如果没有覆盖,如此处所示,它将无效。
我错过了什么?
答案 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()
只会返回一个空列表。你可以安全地检查它是否为空。