`
MR牛奶快跑
  • 浏览: 10107 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

Hibernate:通用DAO到could not resolve property

阅读更多
之前用Hibernate写过一些所谓的BaseDAO(通用的那种),感觉很不错,一个dao可以完成所有的基本功能,心里踏实。
可是渐渐发现这是不够的,Hibernate远没有那么简单囊括。呵呵,给大家拍一下砖。
/**
 * @author liqibin
 * 2010-08-26
 * Base Data Access Object
 * Please fill more method if necessary. Just give others a NOTE
 * Remind me if there are some bugs. 
 * 
 * Cheers, open source.
 * */
public class BaseDAO<T, ID_TYPE extends Serializable> implements IBaseDAO {
    private Class<T> clazz;

	/**
	 * constructor 2 with argument
	 * @param Class<T> c
	 * */
	protected BaseDAO(Class<T> c){
		this.clazz = c;
	}
	
	/**
	 * get the class
	 * @return T.class
	 * */
	protected Class<T> getClazz(){
		return this.clazz;
	}
	
	/**
	 * get session
	 * @return hibernate session
	 * */
	public final Session getSession() {
		return HibernateSessionFactory.getSession();
	}

	/**
	 * save single object with hibernate method
	 * @param T t
	 * */
	public void save(T t){
		this.getSession().save(t);
	}
    ......
    /**
	 * find a list of objects by Criteria or Criteria list
	 * @param Criterion... criterion
	 * */
	public List<T> findByCriteria(Criterion... criterion){
		Criteria crit = getSession().createCriteria(getClazz());
        for (Criterion c : criterion) {
            crit.add(c);
        }
        return crit.list();
	}
	
	/**
	 * find a list of objects by Criteria or Criteria list and order by Order
	 * @param Order order, Criterion... criterion
	 * */
	public List<T> findByCriteria(Order order, Criterion... criterion){
		 Criteria crit = getSession().createCriteria(getClazz());
	        for (Criterion c : criterion) {
	            crit.add(c);
	        }
	        if (order != null) {
	            crit.addOrder(order);
	        }
	        return crit.list();
	}
}

更多具体方法就不写上来了,如果大家愿意看,我很乐意给大家,也希望大家能给我意见。
转正题先。
现在看来,当使用lazyload的时候使用findByCriteria方法时候,很不方便。
譬如现在我有一个ADMIN表,外键指向一个PERSONNEL表的ID需要我需要怎样写呢?如果通过lazyload设置为true,而你又想通过查找ADMIN得到相应的personnel对象,用这个方法显然是不行的。没有地方给我加上createCriteria("personnel")。
当然,通用的东西很是有局限性的。

为此,我把这个类设为抽象类,让更多DAO继承之。为此作扩展。
public abstract class BaseDAO<T, ID_TYPE extends Serializable> implements IBaseDAO ...

那怎样解决这个问题呢?
在继承BaseDAO的XXXDAO上如此写:
List<Admin> admins = adminDAO.getSession().
createCriteria(Admin.class).createCriteria("personnel").
add(Restrictions.eq("login", loginName)).
add(Restrictions.eq("password", pwd)).list();


你会理所当然的得到一个异常:
org.hibernate.QueryException: could not resolve property: login of: cn.edu.scau.diserver.persistence.pojo.Personnel
	at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:67)
	at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:61)
	at org.hibernate.persister.entity.AbstractEntityPersister.getSubclassPropertyTableNumber(AbstractEntityPersister.java:1392)
	at org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:54)
	at org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1367)
	at org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumns(CriteriaQueryTranslator.java:457)
	at org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumnsUsingProjection(CriteriaQueryTranslator.java:417)
	at org.hibernate.criterion.SimpleExpression.toSqlString(SimpleExpression.java:68)
	at org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:357)
	at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:113)
	at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:82)
	at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:91)
	at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1578)
	at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:306)
	at org.hibernate.impl.CriteriaImpl$Subcriteria.list(CriteriaImpl.java:481)
......


为什么呢?
为什么说找不到 login?
答案揭晓:
add(Restrictions.eq("login", loginName))放在了createCriteria("personnel")之后,是的,当时就是这样。
adminDAO.getSession().
createCriteria(Admin.class).
createCriteria("personnel").
add(Restrictions.eq("login", loginName))

这样的写法hibernate是在你personnel中寻找login属性的。(是的,我当时也这么杯具过)
把逻辑顺序理清就没有问题了,如下:
List<Admin> admins = 
adminDAO.getSession()
.createCriteria(Admin.class)
.add(Restrictions.eq("login", loginName))
.add(Restrictions.eq("password", pwd))
.createCriteria("personnel").list();


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics