最近在研究Grails跟db4o的整合。
昨天碰到这么一个奇怪的现象:
下面这段代码中的这句
ObjectSet os = getDb4oTemplate().get(new User(params))
在dev模式下一直报“... cannot be cast to com.db4o.reflect.generic.GenericObject ...”
而在prod模式就正常
class UserService extends Db4oDaoSupport { def objectContainer def login(params) { ObjectSet os = getDb4oTemplate().get(new User(params)) if(os.size() > 0) { println "user found" params.session.user = os.get(0) } else { println "user not found" } } }
而用SODA写query得到的是com.db4o.reflect.generic.GenericObject类的实例
// ObjectSet os = getDb4oTemplate().get(new User(params)) def tpl = getDb4oTemplate() Query q = tpl.query() q.constrain(User.class) q.descend('username').constrain(params.username) q.descend('password').constrain(params.password) ObjectSet os = q.execute()
为什么在dev模式下是GenericObject,而不是我自己的User呢?
我把dev跟prod两种模式下项目目录结构作了对比,有一个显著的区别,就是:前者有个target,下面放着grails/groovy编译得到的classes和其它一些东西;而后者是一标准的J2EE项目的结构,classes都在WEB-INF/classes下,其中就有我的domain class - User。
联想到“The Definitive Guide to Db4o”中的这段话:
read by the generic reflector. This means that the ObjectManager doesn’t have access to the
original class definition. You can help the ObjectManager in displaying the object more naturally
(e.g.,showing the real objects IDs) by providing the original C# or Java classes . The File ➤
Preferences menu option allows you to enter either the directory or the library (.dll or .jar)
files that contain the classes .
虽然它是说Db4o的OM的,但道理应该是一样的。猜想它之所以不能转成User是因为它没看到我的User类。
那我就试着让User出现在它的视野中,试试这句
this.class.classLoader.rootLoader.addURL(new URL("file:///path/to/file"))
貌似无用。
换个方案,把domain classes打成jar包,拷贝到lib下,重启,...,问题解决了,不管是用QBE还是SODA,得到的都是User,而不再是GenericObject了!
但还是有个不方便的地方:每次我修改了domain class,都得重新打包,重新启动,损害了Grails开发的快速特性。
各位路过的朋友有没有完美的解决办法让它实现hot swapping?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。