`
miman2008
  • 浏览: 37741 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

错误随手记

阅读更多
  • 2010年12-5

今天在一个DAO中尝试对一个数据执行先查询再更新的操作,结果后台提示出现了sql语句 

 Hibernate:              select group_id from fnd_groupid where id= ?
Hibernate:             update fnd_groupid set group_id= ? where id = ?

本来是很简单的一个操作,但是数据库里面的值却始终不更新。

之前的代码如下:

   SQLQuery query = this.getSession().createSQLQuery("select group_id from fnd_groupid where id= ?");
   query.setLong(0, 1L);
   Long nextVal = StringTools.parseLong(query.uniqueResult().toString());
   SQLQuery queryUpdate = this.getSession().createSQLQuery("update fnd_groupid set group_id= ? where id = ? ");
    queryUpdate.setLong(0, nextVal+1);
    queryUpdate.setLong(1, 1l);
    queryUpdate.executeUpdate();

 

后来google一下,才发现我的操作很有问题,我连续取出当前会话进行操作,前面的查询操作可以进行,但是此时会话还在进行中,我后面再次取到当前会话,并执行更新操作,这个操作始终无法完成。多次操作应该使用事务,只有提交事务之后才会生效。这其中涉及到hibernate的一级缓存机制。

这说明埋头写代码真的没啥用,原理的东西很多尚待研究,任重而道远~~

修改后的代码如下:

	Session session = this.getSession();
		Transaction transaction = session.beginTransaction();//启动事务
		SQLQuery query = session.createSQLQuery("select group_id from fnd_groupid where id= ?");
		query.setLong(0, 1L);
		Long nextVal = StringTools.parseLong(query.uniqueResult().toString());
		
		SQLQuery queryUpdate = session.createSQLQuery("update fnd_groupid set group_id= ? where id = ? ");
		queryUpdate.setLong(0, nextVal+1);
		queryUpdate.setLong(1, 1l);
		queryUpdate.executeUpdate();
		transaction.commit();
		session.close();
		return nextVal;

 

  •  2010-12-8

           

与Hibernate DetachedCriteria有关的分页问题

这是本人做项目数据库移植的时候遇到的一个最典型的问题,在查询总量的时候,会报如下错误

ORDER BY 子句中的列 "fnd_code.CODE_ID" 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中。

 

当时百度google了很久,感觉网上都是泛泛而谈,没有从根源解决这个问题。下面就这个问题分析一下。

public List findPageByCriteria(DetachedCriteria criteria, int pageFirst, int pageMax){
		log.debug("finding instance page by criteria");
		try {
			List results = getHibernateTemplate().findByCriteria(criteria, pageFirst, pageMax);
			log.debug("find page by criteria successful, page size: "
					+ results.size());
			return results;
		} catch (RuntimeException re) {
			log.error("find page by criteria failed", re);
			throw re;
		}
	}

 

这是BaseDao中的一个方法,使用hibernate管理数据库连接的时候,就是通过下面几行代码

getHibernateTemplate().findByCriteria(criteria, pageFirst, pageMax);
//其中,criteria是查询语句,pageFirst就是要查第几页,而pageMax就是总页数,hibernate会自动将这一页的内容取出来 

来进行分页查询的。

    但是在进行分页查询以前,必须要知道记录总数,以及分页信息,这个通常手动指定。知道这些信息后,再通过记录总数调整分页信息,调整方法如下:

public void adjustByTotalRow(int total){
		totalRow = total;
		if(totalRow < 1){
			page = 0; //当前页
			pageRow = 0; //页面记录数
			totalPage = 0;//总页数
			totalRow = 0;//总数据量
		} else {
			//设置总页数
			totalPage = (totalRow / pageMax) + ((totalRow % pageMax) == 0 ? 0 : 1);
			//调整页号
			if(page > totalPage){
				page = totalPage;
			} else if(page < 1){
				page = 1;
			}
			//计算页面记录数
			pageRow = totalRow - (page - 1) * pageMax;
			if (pageRow > pageMax){
				pageRow = pageMax;
			}
		}
	}

 

下面问题出来了,需要获得记录总数,最简单的代码如下所示

select count(*) from fnd_code order by code_id

 

但是令人蛋碎的是,一模一样的一个sql语句,在oracle中正常运行,但是sql server竟然报错,就是我上面贴出来的这个错误。分页的问题就是因为这个语句出来的。

在我的service中,进行如下调用,需要说明的是,现在传进来的criteria是有order的。

protected List findByPage(BaseDAO dao, DetachedCriteria criteria, PageMeta page) throws ServiceException{

		if (page == null) {
			return dao.findByCriteria(criteria);
		} else {
			int total = dao.findTotalByCriteria(criteria);//获取记录总数

			if (total == 0) {
				// no record found
				return null;
			}
            
			page.adjustByTotalRow(total);//这个方法上面有贴出来,调整分页信息

			// fetch the result page
			if (page.getPage() < 1) {
				// no fetch needed
				return null;
			}

     List results = dao.findPageByCriteria(criteria,page.getPageFirstRow(), page.getPageMax());//分页查询
}

  在service中,获取记录总数就会调用上面类似的sql语句,错误也就在此产生的。 

啰嗦这么多,只是想也把分页的方法大致描述一下,方便理解。这个问题解决起来很简单,我们要把addOrder操作加到获取记录总数之后。下面是我修改的BaseService

protected Order order;//定义一个字段Order
              /*此方法供外部调用,不再给criteria添加Order,而是将order给service
               */
	public void addOrder(Order order){
		this.order = order;
	}
	protected List findByPage(BaseDAO dao, DetachedCriteria criteria, PageMeta page) throws ServiceException{

		if (page == null) {
			return dao.findByCriteria(criteria);
		} else {
			int total = dao.findTotalByCriteria(criteria);

			if (total == 0) {
				// no record found
				return null;
			}
            
			if(order != null){
				criteria.addOrder(order);//获取记录总数以后,再将order加入
			}
			// adjust the page meta info by the actual total
			page.adjustByTotalRow(total);

			// fetch the result page
			if (page.getPage() < 1) {
				// no fetch needed
				return null;
			}

	List results = dao.findPageByCriteria(criteria,page.getPageFirstRow(), page.getPageMax());
}

 

 作了如下调整后,分页问题不复存在,当然我的方法可能不太好,如果哪位朋友有不同解决办法,可以留言交流,谢谢。

 

  • 2010-12-14

今天处理日期时发现一个问题,日期越减越大,为啥?

原来是基本数据类型的问题,Java默认数值类型为int型,下面的运算超出范围,越界之后数值变为负数,因此出现这个问题。

sDate.setTime(eDate.getTime() - 180*24*60*60*1000);

 应该在后面加上类型转换:

sDate.setTime(eDate.getTime() - 180*24*60*60*1000 L);

 

这种类型的错误太蛋疼了~~

 

1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics