Agile
-
Hibernate POJO 是真正的POJO吗?
2006-04-05
今天晚上改一个程序,发现了一个很奇怪的问题,hibernate所说的POJO并不像其宣称的那样,可以当做普通的java对象使用,至少有时不注意的时候会出问题,在写程序的时候,千万要注意这种情况。
晚上遇到的问题是这样子的,有一个对象Document,用Spring的HibernateTemplate load之后,我设置了这个对象的一个属性,例如一个叫做md5的属性,代码如下:
...开始事务
Document doc = hTemplate.load(new Interger(documenId),Document.class);
String content = doc.getContent();
String md5 = MD5.get(content);//计算文档内容的md5值
doc.setMd5(md5);
/*
getDocumentByMd5 的定义 :select doc.id from Document doc where doc.md5=:md5
在查询之前,数据库里的md5是惟一的,没有md5码相同的Document
*/
Listlist = hTemplate.getHibernateTemplate().findByNamedQueryAndNamedParam("getDocumentByMd5",
"md5", md5);
....结束事务
返回的list结果的里按照我的思维应该是空的,但是结果是返回的list的第一个元素的值就是doc的对象id。
按理讲程序的事务还没有提交,doc也没有被update,怎么就会查出结果了呢?太奇怪了。
研究了一下Hibernate2.17c的SessionImpl源代码,发现下面的注释,在作查询前,Hibernate要先检测在查询语句中出现的表涉及的对象是否被修改过,如果被修改过,那么先提交这些修改,之后再查询。这也解释了为什么刚修改过的对象,还没有提交修改,就在查询结果出查出来了。
/**
* detect in-memory changes, determine if the changes are to tables
* named in the query and, if so, complete execution the flush
*/
private boolean autoFlushIfRequired(Set querySpaces)
我就在想,这样的POJO是真正的POJO吗?而这些细节一般很难被注意到,反正我以后是不敢再这样子用了,在用Hibernate的时候,从它那儿得到的POJO对象小心使用,它可不是“真正的POJO”。
今天刚发现Groovy有vim的插件,很好用,语法加亮显示,下午在公司把它装上后,工作效率明显提高,不在满屏白字了,呵呵,从这里可以下载到这个插件http://www.vim.org/scripts/script.php?script_id=945,安装很方便。
Groovy目前竟然不支持java标准的for (int i=0;i<10;i++) 循环,别的样式的for循环倒是有好几种,郁闷中。
注:上面说到的Hibernate的问题可以通过session.setFlushMode(FlushMode.COMMIT)设置提交来解决,abside的指点很正确,非常感谢。Hibernate有四种FlushMode:NEVER,COMMIT,AUTO,ALWAYS,默认是AUTO,工作还需要再细心些。
(2006.06.07)
-
最近的总结
2006-01-24
又是一个多月没有写日志了,总是在瞎忙,今天就把最近的情况总结一下。
1.Linux
取得Shell运行时所在的目录
功能:主要取得了当前运行脚本的绝对目录和参数,这个脚本是晚上帮朋友写的,以前也想写一个类似的脚本,一直没有动手,效果还不错。
#! /bin/sh
name=$0
args=$*
name=`echo $name|sed 's/^\.\{1,2\}\/\{1,\}//'`
if [ ! $(echo $name | grep '^/' - ) ]; then
if [ `pwd` == '/' ]; then
name=/$name
else
name=`pwd`/$name
fi
fi
script=`/bin/ls -l $name | awk '{ print $NF; }'`
while test -h "$script"
do
script=`/bin/ls -l $script | awk '{ print $NF; }'`
done
bindir=`dirname $script`
echo "BaseDir:$bindir Args:$args"在两台机子之间拷贝文件
cat <file0> | ssh <host> "cat > /destfilepath"
这个脚本需要在两台机子之间配置ssh,有可能需要输入密码,很是方便。
2.Tagpstry
换了新的工作,对一些j2ee的框架接触的少了许多,最近在用tapestry(tacos)+spring+hibernate做一个东西,另外用了jdk5.0,用了其中的泛型和annotation的功能,最喜欢String.fromat这个功能了,强。
有时用tapestry进行一些特殊功能的实现,不是太灵活,特别是在基于tacos时,例如当提交form的时候,想要为用户提供一个确认的窗口,直接使用tacos的时候,是很难办到的,我找了它的好些component也没有找到类似的功能,用了一个比较别扭的办法:
<form jwcid="pageForm">
<div>
<label>
<span key="title">标题:</span> </label>
<input name="title" type="text" size="60" value="ognl:document.pageTitle" jwcid="title@TextField"/>
</div>
<div>
<a jwcid="@tacos:AjaxDirectLink" name="dp" id="dp" listener="ognl:listeners.deletePageData" parameters="ognl:{pageDataId}" updateComponents="ognl:{'auditResult'}"/><!--在这个a tag中触发jwcid dp的click事件-->
<a href="javaScript:var ok = window.confirm('confirm?');if(ok){did.style.display='none';document.all.dp.click()}"><span key="deletePageData">删除此记录</span></a>
</div>
</form>使用Tapestry最大的感触是刚开始的时候有些不大适应,用的习惯后就对它强大的功能很是佩服,而且在DW中设计页面正如它所声明的一样,基本上不影响整体页面的效果。
3.Java
说起来实在是不好意思,最近才明白了String.replace和String.replaceAll之间的区别,前者不使用正则表达式,而后者使用正则表达式来执行替换操作。
Jrockit是一个很强大的jvm,利用它提供的工具,可以动态的监视jvm中内存使用的状态,从Bea的文档上知道了Jrockit5.0有内存泄漏检测的工具,令人郁闷的是一直也没有成功的使用这个功能,不知道是否是由于License的限制。Jrockit的性能通过调整jvm的参数可以有很大的提升,公司有一台服务器,双CPU,把Jrockit的垃圾收集改为parallele,同时把-Xmx设为1000M,系统的响应速度得到了很大的提升,呵呵。
Hibernate删除的时候,可以通过它来删除Object,但如果对象的个数多于一个,还是用sql来删除的好,不要猜测数据的多少,因为我们不好预测到所有可能发生的情况,在sql server使用Hibernate的delete方法的时候,按照hibernate的做法,它会先找到所有要删除的对象,之后才删除,我在测试一个程序的时候,发现sql server的后台进程阻塞了好几个,全是由于事先认为数据量不大,使用Hibernate删除不会有太多的影响,就懒得用jdbc来直接删除,其实通过spring的JdbcTemplate非常方便。
4.Python
前些日子用Python写了个程序,先在windows上写,后传到Linux上运行,发现总是不对,在网上搜索了一下,有高人说可能是由于windows和Linux之间换行符的不同赞成的,可以用dos2unix命令解决,不过这个命令不是在所有的Linux发行版上都有的。
5.其它
最近GCT考试结果出来了,还好被录取了,又要上学了,呵呵。今天上午把亲爱的GF送上火车了,心里的一块石头总算落下来了,不过又要给自己找火票了,晚上有同学打过电话来说,回大同的票已经没有了,郁闷,该怎么回家呢?明天再说吧。
-
Myeclipse的Hibernate工具
2004-09-09
昨天下载了一个新版MyEclipse3.8.1,感觉挺爽,校验JSP,根据数据表生成Java文件和Hibernate的配置文件,图形化的Struts开发,挺不错! -
让我兴奋的Hibernate
2004-04-27
刚做完了一个小东西,用了久未用的Hibernate,顺便看了看Hibernate最新的发展-Hibernate3,其中的许多新特性让我兴奋不已,尤其是对存储过程的支持,更是值得期待,我想以后Hibernate可以成为o/r映射的标准了:)
-
A Simple Data Access Layer using Hibernate
2004-04-09
-
不要使用Hibernate自带的连接池
2004-03-03
Hibernate自带的连接池有比较严重的问题,如果没有使用事务,或者使用了事务但是没有提交(回滚),那么它会经常得不到新增加的数据,建议使用DBCP或其它的连接池.
例如,下面的代码,如果在新增加了数据或修改后,它不会马上得到新的数据,惟一的方法就是把注释去掉,在多数据情况下它会得到新的数据。
HibernateBase hb = new HibernateBase();
try {
//hb.begin();
List list = hb.listQuery("select company from Company company",null);
Iterator ir = list.iterator();
while(ir.hasNext()){
Company c = (Company)ir.next();
System.out.println("compnay name:"+c.getName());
}
//hb.commit();或//hb.rollback();
}
catch (PersistentException e) {
e.printStackTrace();
throw e;
}
finally{
hb.release();
}这个问题可能是由于Hibernate自带连接池的实现问题,具体情况有待于以后证实。其实这个连接池在实际项目中使用的并不多,但是在开发、测试的时候有较多的使用,所以如果在测试时发现这种问题,更换连接池试试:)
-
Hibenate映射注意事项
2004-02-03
在建立父类与子类映射关系时,要同时建立子类和父类的双重关系即在父类中有子类的set,同时子类有父类的引用。如果仅仅建立子类对父类的引用则在删除父类对象后,不能正确读取子类对象。 -
Hibernate中文档
2004-02-02
刚才发现了一个好东东,Hibernate的中文文档,虽然没有译完,但真是不错了。







