2007-12-18
ejb环境下的org.hibernate.TransientObjectException
以前ear部署时CallByValue设置的是false(ear-deployer.xml), 后来改成了true, 然后就不能加分了, 注册还是可以的, 就是一直报org.hibernate.TransientObjectException的异常.
代码大概是这样的:
Consumer c = new Consumer();
c.setUsername("uname001");
c.setPassword("pwordddd");
service.save(c);//1
service.addPoints(c, 300);//2
service是对EJB的引用(Stateless)
故事就是由EJB引起的.如果CallByValue=false, 在执行"1"后执行
System.out.println(c.getId());//841
返回值不是空, 如果CallByValue=true, 返回值就是空.
分析一下 : CallByValue时, Hibernate不能同步c的id.
POJO有3种状态, Transient, Persistent, Detached, Transient是用"new" 实例化的, 执行hibernate的save操作, 会存储到数据库的同时更新这个对象, 变成Persistent.而在CallByValue=true 的情况下, hibernate无法更新到这个对象, 也就是说, 在上面1步骤执行的时候, hibernate没有办法更新c这个变量.
废话多了, 好像也没大说明白....
2007-11-20
访问EJB
javax.ejb.EJBException: Invalid invocation of local interface (null container)
如果想独立启动junit测试访问ejb, 需要把ejb声明为Remote.
2007-11-19
jms定时发送
jms标准并未提供定时发送的规范, 所以根据各实现的不同, 有不同处理方法, 在jboss中, 设置如下:
//....
Message msg = session.createObjectMessage();
msg.setLongProperty("JMS_JBOSS_SCHEDULED_DELIVERY", time());
//....
sender.send(msg);
其中time()返回的是msg发送的时间点, long类型. 如果是想立即发送的话, 值应该是
System.currentTimeMillis()
tss讨论帖
2007-11-16
今儿总算是明白了, 为什么那么多人追着学xml
非常清晰直观的sample.
我觉得非常突出的一个优点是, 强制web designer更标准化地去做xsl.
用html的话, 就很随便了, 可以拼凑出页面来.
xml数据是独立出来的, 也方便供其它接口调用(ws?, 采集数据?)
终于发觉它值得学了.....
2007-11-01
函数式编程
包括回调(callback)这样的技巧.
感觉象一种"操作注入" , 相对"依赖注入"来说.
实现有Erlang和Haskell等, 高并发, 据说Erlang的http服务器比apache快15倍
复杂的系统倾向于用这种语言, 代码比较优美, 相对较少. ref=>越少的代码越不容易出错
少废话, 来几个链接
http://www.ibm.com/developerworks/cn/web/wa-javascript.html
developerWorks上用js解释的
http://www.ibm.com/developerworks/java/library/j-fp.html
java中的函数式编程
http://code.google.com/p/pure-functional-java/
一个小项目, 大致实现了函数式编程.
http://chn.blogbeta.com/232.html
一个从几千年开始讲起的函数式编程的历史.
2007-09-24
慎用System.exit()
用main启动spring, 然后main就一直等, 一直等...spring就嘿咻嘿咻地启动线程, 发邮件, 启动线程, 发邮件.....
然后就完成任务了~~~ :).
后来, 又给了我一个邮件列表, 这次要带附件发送...
问题来了, 程序还没等邮件发完, 就终止了....
然后发现, 在读邮件列表时, 是一行一行地读的, 每读一个, 就发送给spring, 让spring去嘿咻嘿咻, 如果读到最后一行, 就执行
System.exit(0);
问题就是这段代码了, 把它修改成
return;
OK了, 阳光明媚 :D
虽然读到了最后一行, 但是, 后台的发送程序还没结束.
2007-09-06
发现spring写的代码跟我的一样, 偷乐.....
不过, 最后还是把我的代码删除掉了.....
这是一个bug么?Spring.BeanWrapper
class A{
BeanWrapper bw = new BeanWrapper(this);
private String[] sa;
//setter/getter....
}
给sa属性加了个属性编辑器StringArrayPropertyEditor
我觉得, 这么调用, 应该不会出问题:
A a = new A();
a.setSa(new String[]{"a", "b", "c"});
//我期望它的结果应该是 "a,b,c"
a.bw.findCustomEditor(String[].class, "sa").getAsText();
结果, 却是空, 不是找不到属性编辑器, 当你通过属性编辑器去获取属性值时, spring不会真正地去a这个类里面实时查找.只有当执行这句,
上面的代码才能得到预期的结果:
a.bw.setPropertyValue("sa", new String[]{"a", "b", "c"});
令人失望....咋就不去inspect一下'a'这个类捏?
2007-09-05
2007-08-31
又一次谈classloading--java.lang.VerifyError
后来, 修改jbossweb-tomcat55.sar/META-INF/jboss-service.xml, 把Java2ClassLoadingCompliance属性设置为true, 就OK了.
这个属性是jboss集成tomcat用的, 它的意思是, 是否把java2的"父类优先"加载模型替换为servlet 2.3的"web容器优先"
2007-08-29
jobss类加载
<jboss-app>原文
<loader-repository>some.dot.com:loader=webtest.ear</loader-repository>
</jboss-app>
然后我就照这个办了, 后来发现还不行, 说是mdb(部署了一个message-driven bean)不合规范:
section:15.7.4
The message driven bean must declare one onMessage method
后来才发现, 不知道哪个傻X把geronimo-j2ee-spec.jar放到ear包里来了, NND, 估计是geronimo与jboss验证方法不一样吧.
去掉就OK了. 还有个关于logging的, 不加jboss-app.xml的话, 会自动把你自己ear内的logging.jar忽略掉(而用jboss服务器的), 加了jboss-app.xml, ear的classLoader也会把ear里面的logging.jar加载上 , 然后Log对象就发现它有两个版本(一个jboss的, 一个ear载的).就会报错(检查的还挺仔细)
再这么下去, 快成jboss专家了....
--
It's Hard to Define, But I Know it When I See it…
2007-08-28
class 版本
部署ejb的时候就出这问题, 也会出classNotFoundException. 原因是jdk5编译出来的class在jdk4上面不能.
这种问题...真让人无奈....
--
It's Hard to Define, But I Know it When I See it…
2007-07-25
因无索引导致的性能问题
select count(*) from a, b where a.bid = b.bid;
其中a表中的bid是b表的id外键. 每个表大概有7k条记录.这个查询每次都耗时30s, 后来把a表中的bid字段建立个属性, 速度就快多了, 大概是300ms~1s.
以前一直没觉得索引有这么神奇的效果.....
--
It's Hard to Define, But I Know it When I See it…
2007-07-24
接口参数类型
update(FriendLink link);
接口的实现是这么写的:
update(FriendLink link){
dao.update(link);
}
后来, 发现有弊病在: 这个接口依赖这样的事实: link已经存在于数据库中 .这样很容易产生潜在的不安全性, 外部的任何程序都可以随意构造一个FriendLink实例(而不是从数据库中取然后稍加修改而成的), 然后传入到这个接口, 然后产生异常. 还有个问题就是, 它限制了访问媒介为java对象(须先构造出FriendLink对象来, 才能访问到这个接口), 不利于其它形式的访问(如webServices, REST等---虽然可以, 但是须对FriendLink中accessor信息了然于胸). 所以应修改如下:
update(long friendLinkId);
传入基本类型(long), 声明说会对这个(id为friendLinkId的FriendLInk)作更新, 这样, link已经存在于数据库中 这样的谓词是由接口内部来判断处理的. 对于其它形式的访问, 基本类型都是被支持的. 至于update的信息, 可以以参数形式, 或函数名形式展现, 如下:
update(long frindLinkId, Date accessDate); ①
或
updateAccessDate(long friendLinkId);②
象②这样的只传入id的接口, 依赖于"执行更新所需信息可以从接口上下文得到", 比如当前时间等.所以应用面比较狭窄, 不知道具体应该怎么处理(map参数?) :( (还是动态语言比较好, 象js的arguments参数很灵活)
--
It's Hard to Define, But I Know it When I See it…
date 与 timestamp 类型
timestamp比date精确.
用date只能搞到日期, 时间得不到, 所以在sql里面进行alter时, 只有timestamp=>date的转换, 如果想执行相反的转换会报异常.
如果用hibernate进行映射, 一般来说是 java.util.Date=>timestamp.否则, 标志性的异常信息是batch update exception (不过有个有趣的现象是, 如果你设置hibernate.jdbc.batch_size 为0的话, 就能顺利执行, 应该是hibernate的bug)
P.S. 如果是用xdoclet映射字段, 不要这么写:
@hibernate.property column="createDate" type="date"
把type写全:java.util.Date. 否则会引来不必要的麻烦: hibernate会把它错当成java.sql.Date :(
--
It's Hard to Define, But I Know it When I See it…
2007-06-28
将unicode转成中文及其它
原理就是把.properties中的所有"\uxxxx"形式的转成对应的中文.
String r = FileUtils.readFileToString(new File("d:/aa.TXT"), "utf-8");
Pattern p = Pattern.compile("\\\\u([a-zA-Z0-9]{4})");
String t = "";
Matcher m = p.matcher(r);
while(m.find())
{
t = m.group(1);
r = r.replaceFirst("\\\\u([a-zA-Z0-9]{4})", String.valueOf(Character.toChars(Integer.parseInt(t, 16))));
}
System.out.println(r);
那个parseInt中的参数16表示t是16进制的字符串.
感觉还比较简洁的说~~~
P.S. FileUtils是jakarta commons.io里的
--
It's Hard to Define, But I Know it When I See it…
2007-06-14
httpclient提交中文的问题.
本来想的是看看httpclient里面哪里编码不对了, 改成utf-8,如此的思路.
后来, 发现给http head加个meta就成了:
post.addRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
真的是不能想太复杂鸟...
--
It's Hard to Define, But I Know it When I See it…
2007-06-07
其实, 除了actionForm还有更简便的方式的~
FriendLink bean = new FriendLink();
ServletRequestDataBinder binder = new ServletRequestDataBinder(bean, "link");
CustomDateEditor editor = new CustomDateEditor(new SimpleDateFormat("yyyy-M-d"), true);
binder.registerCustomEditor(Date.class, editor);
binder.bind(request);
这样就自动给bean注入值了, 而且它已经自动拥有了处理multipart的能力, 真是不错. 只是没有处理日期格式的能力, 但是象上面的代码就可以了.
顺便贴几个链接:
link 用spring做项目时的一些设计上的技巧.
link ServletRequestDataBinder的官方文档.
link 处理日期格式的方法就是从他这抄袭来的, 呵呵.
--
It's Hard to Define, But I Know it When I See it…
2007-05-13
补: autoboxing
P.S. NPE=NullPointerException(看来这个异常很常见呢)
2007-03-25
java.sql.SQLException: java.lang.NegativeArraySizeException
在执行分页查询的时候, 如果是这么写:
select * from orders limit 1, 30;//第一页的30条
没有任何问题.但是把它放到存储过程里(参见前一篇文章), 就会出那个exception,只要是页不满的情况都会报exception.但是有个特别的现象, 如果你把orders表清空, 然后执行java, 不会报错, 只有当行数大于某个值并且页不满才会报Exception.
非常不明白....
相对详细的代码在这:link
2007-03-24
myeclipse差劲
特别是UML, 当初看着感觉还不错, 用着问题就出来了: 不能识别泛型, 不能导入类, 删除类/关系删不干净, 生成的代码错误百出.最要命的是它还搞罢工, 本来就是serialize的object, 出点问题就死翘翘了.慎用....非常不稳定
mysql的分页存储过程
select * from test limit 3, 20;
表示每页显示20个, 第3页.这种写法不能通过PreparedStatement执行, 因为它是编译过的, 存储过程同理.所以这样写不会成功:
create procedure pager (in pno int, in psize int)
begin
declare pp int default 0;
set pp = (pno - 1) * psize;
select * from pager limit pp, psize;
end
应该算是mysql的bug.
有个折衷的办法:
create procedure pager (in _pno int, in _psize int)
begin
prepare stmt from "select * from test limit ?,?";
set @pno = (_pno - 1) * _psize;
set @psize = _psize;
execute stmt using @pno, @psize;
end
link, link
2007-03-22
autoboxing的bug么?
Double d = null;
double e = d;
System.out.println(e);
这会出问题, d不能自动autounboxing为double.会报nullPointer异常.
所以在做ibatis映射的时候, bean的属性需要是Double类型的.否则会有不必要的问题.
失望....
2007-03-15
dbdesigner不能连mysql的问题.
cannot connect to mysql : invalid username/password
把password在mysql中更新一下就好了:
mysql> set password for 'root'@'localhost' =OLD_PASSWORD('newpassword');
一个与老版本兼容的问题, link
2007-03-13
目前Ajax主要存在的问题
- Accessibility问题。
- 主要开源框架(prototype和dojo)文档不足。
- 缺乏好的跨域机制。XMLHttpRequest不行,Doug Crockford的JSONRequest不错,但是很难被微软采纳。
- 跨浏览器编程仍然非常麻烦。
- 对Comet (HTTP Streaming) 的重要性仍然认识不足。
2007-03-09
全排列算法
有1, 2, 2, 3, 4, 5, 这六个字符, 打印出它们的所有排列顺序.
想了老半天, 结果就是这样滴:
public class SnippetTest
{
private void perm(char[] a, boolean[] f, String r)
{
for(int i = 0; i < f.length; i++)
{
if(!f[i])
{
f[i] = true;
if(r.length() == 5)System.out.println(r + a[i]);
perm(a, f, r + a[i]);
f[i] = false;
}
}
}
public static void main(String[] args)
{
char[] a = new char[]{'1', '2', '2', '3', '4', '5'};
boolean[] f = new boolean[6];//default is false
String r = "";
new SnippetTest().perm(a, f, r);
}
}
嗯....相当简洁的说.而且也是可以扩展的, 赞自己一个, 太TNND牛了
2007-02-27
今天这几篇都是转移过来的
现在要离开公司了, 就把这些日志整理出来, 重新发布到blogspot上来了.
其实很长段时间以来都没很好得写过日志了. 感觉总是抽不出时间来.
以后会多多写了 :)
从editplus编译/运行java
天天对着editplus也米好好研究过, 原来它还有这个能力
在给editplus设置参数时发现user tools这个选项, 就想到了java的编译和运行命令.虽然有了eclipse方便了很多, 但是有时还是有命令行的需要.不扯废话, 正题:
在user tools选项里选择add tools>>Program.把javac.exe加进去. Argument设置为$(FilePath), Initial Directory设置为$(FileDir).最好把”capture output”也选上, 这样的话就能看到控制台的输出信息了.
类似的, java命令也这么搞:
Argument : -classpath $(FileDir) $(FileNameNoExt)
Initial Directory : $(FileDir)
保存, 然后新建个java文件, 从tools菜单里选择”编译” 然后再”运行”, 嗯.OK啦, yeah~
在eclipse中搜索中文
一般都是修改别个的代码, 自己会手动加些注释在上面, 但是时间长了就忘记了哪里修改过了, 又米有cvs.
还好, eclipse的search功能还真是强大, p服p服
[\u0100-\uffff]+
这段regexp可以查找出所有的中文来, 如果想只在java文件里搜索, 就加个”*.java”就好了
察看端口冲突
机器上开着好多程序, 几个web服务器, 还有cvs,还有其它的msn, gtalk等, 有时候要想再启动服务会出现错误说端口已经被占用, 一开始的时候不知道是哪个程序占用的, 就一个一个关掉试, 后来找到个好办法:
netstat -b
这个命令可以察看已经打开的端口是由谁打开的.看了觉得MSN开了N多的端口, 真是…
yourkit 连到jvm
jdk1.4:
-Xrunyjpagent:port=10010,dir=d:\dev\yourkit\snapshots
jdk5.0:
-agentlib:yjpagent=port=10010,dir=d:\dev\yourkit\snapshots
我的yourkit版本是5.5, 在jdk6.0上试运行了下, 不行, 查了下, 好像yourkit6.0才支持jdk6的.
不好….
将ant输出日志redirect
ant -logfile ant.log mytarget
这样就OK了, 还有其它的listener&logger等, 可以参看ant的manual, Loggers & Listeners 目录
安装wordpress
问题就在php-mysql.dll没有安装, 但是俺是下载的标准的php安装文件装的吖, 怎么还会这样捏?原来它默认好像是不安装的, 倒….
回顾一下具体的安装步骤吧, 要不又忘记鸟:
- 安装apache_2.2.2-win32-x86-no_ssl.msi
- 安装mysql,好像是5点几的, 建个db名字为wordpress
- 安装php-5.2.0-win32-installer.msi
- 修改{php.home}/php.ini文件, 将 ;extension=php_mysql.dll取消注释, 然后设置下对应mysql的host, username, password就成啦