无数据源情况下,Controller.getModel(MyModel.class)异常,导致远程传输Model困难。。。

糊搞 发布于 2014/03/28 10:15
阅读 787
收藏 0

波总,在使用JFinal开发分布式系统时(Web前端没有数据库),想用Model进行远程传输给服务端进行处理。因为Model使用方便,可直接用于页面数据对象,传输给服务端也不需要进行转换,拿来应用。

希望是美好的,可在使用的过程中出现问题,Controller.getModel(Blog.class)抛出如下异常:


[http-8082-1] ERROR com.jfinal.core.ActionHandler - /blog/update
java.lang.RuntimeException: The TableMapping of model: cn.gh.duboo.demo.model.Blog not exists. Please add mapping to ActiveRecordPlugin(activeRecordPlugin.addMapping(tableName, YourModel.class)).



原因就是没有启用ActiveRecord,导致TableMapping中没有注册Blog。

为了绕过此问题,我使用的方法有两种:

1.修改JFinal源代码,将异常屏蔽(很龊的作法)。

2.创建与Model对应的Dto对象,工作和代码量大,Model和Dto转换使用反射,降低性能。


希望波总和各位JFinal爱好者能给个有效的方案(不想采用Record)。


加载中
0
JFinal
JFinal

给两个方向的解决方案:

1:Controller.getModel(...) 对 Model的转换依赖于 TableMapping(1.6版本),只要写程序创建立好其中的数据就可以,程序可以写得通用一些,通过读取配置就可以建立起来。或者可以为各服务端写个 api,先同步TableMapping中的数据,再 getModel

2:Controller.getModel(...) 其实是支持普通 java bean 的,可以getModel(JavaBean.class),这样就可以为远程传输建立一个适配层,提供普通 java bean,然后再每个普通 java bean 中写个 toModel() 方法转化一下

   个人倾向于方法一,可扩展性好,api 写好后就一劳永逸 

0
糊搞

引用来自“JFinal”的评论

给两个方向的解决方案:

1:Controller.getModel(...) 对 Model的转换依赖于 TableMapping(1.6版本),只要写程序创建立好其中的数据就可以,程序可以写得通用一些,通过读取配置就可以建立起来。或者可以为各服务端写个 api,先同步TableMapping中的数据,再 getModel

2:Controller.getModel(...) 其实是支持普通 java bean 的,可以getModel(JavaBean.class),这样就可以为远程传输建立一个适配层,提供普通 java bean,然后再每个普通 java bean 中写个 toModel() 方法转化一下

   个人倾向于方法一,可扩展性好,api 写好后就一劳永逸 

1:您的意思是在JFinal的Config中,将所有Model所需要的数据先手动注册到TableMapping中,绕过ActiveRecordPlugin启动时通过数据库映射表结构到TableMapping的过程?这样的工作量大,因为要注册数据库表的各个列的列名和数据类型。维护时容易遗漏和搞错数据类型,而且在表数据表变化时加大工作量。

2:本质上还是个Dto,与我提出的问题中就已经说明这写法很累,效率也不高。我宁愿写个BaseController覆盖下面三个方法,达到ModelInjector的功能:

getModel(Class<T>, String) <T>
getModel(Class<T>) <T>
keepModel(Class, String)


很感谢波总的意见,最终还是会选择第一种方案。。。

0
糊搞

此问题的延续。。。

采用第一种方案后,我做了个Mock Model注册:

// 用户
Table user = new Table("user", User.class);
user.setColumnType("id", String.class);
user.setColumnType("login_name", String.class);
user.setColumnType("nick_name", String.class);
。。。。。。



但是,由于Table.java中,没有在第一时间初始化columnTypeMap,导致空指针。因此希望波总尽快修改代码,columnTypeMap声明的同时初始化它:

受保护的方法void setColumnTypeMap(Map<String, Class<?>> columnTypeMap)中,只需要改为:

this.columnTypeMap.putAll(columnTypeMap);



谢谢

0
错觉
错觉

我觉得你的“ 1.修改JFinal源代码,将异常屏蔽(很龊的作法)。”这个方法是最好的!!

糊搞
修改源码一定要有正当理由,而且修改后的代码要能够应用到JFinal新版本中,,,显然我的修改不满足前面的条件。
0
JFinal
JFinal

引用来自“糊搞”的评论

此问题的延续。。。

采用第一种方案后,我做了个Mock Model注册:

// 用户
Table user = new Table("user", User.class);
user.setColumnType("id", String.class);
user.setColumnType("login_name", String.class);
user.setColumnType("nick_name", String.class);
。。。。。。



但是,由于Table.java中,没有在第一时间初始化columnTypeMap,导致空指针。因此希望波总尽快修改代码,columnTypeMap声明的同时初始化它:

受保护的方法void setColumnTypeMap(Map<String, Class<?>> columnTypeMap)中,只需要改为:

this.columnTypeMap.putAll(columnTypeMap);



谢谢

       columnTypeMap 在第一时间没有初始化是因为当时无法知道 containerFactory 的具体类型,用户有可能对此 ActiveRecrodPlugin进行了 arp.setContainerFactory 操作,不同的 containerFactory 会生成不同类型的 map 对象。

     不过这个方法倒是可以考虑放开,只不过放开后就对封装性有影响,因为无法避免 jfinal 之外的代码对 columnTypeMap 进行修改,从而就有导致系统出错的可能。我考虑用 CPI 的方式开放出来。

    由于 columnTypeMap 没有在第一时间进行初始化,所以才有了 setColumnTypeMap 方法的存在

0
糊搞

引用来自“糊搞”的评论

此问题的延续。。。

采用第一种方案后,我做了个Mock Model注册:

// 用户
Table user = new Table("user", User.class);
user.setColumnType("id", String.class);
user.setColumnType("login_name", String.class);
user.setColumnType("nick_name", String.class);
。。。。。。



但是,由于Table.java中,没有在第一时间初始化columnTypeMap,导致空指针。因此希望波总尽快修改代码,columnTypeMap声明的同时初始化它:

受保护的方法void setColumnTypeMap(Map<String, Class<?>> columnTypeMap)中,只需要改为:

this.columnTypeMap.putAll(columnTypeMap);



谢谢

       columnTypeMap 在第一时间没有初始化是因为当时无法知道 containerFactory 的具体类型,用户有可能对此 ActiveRecrodPlugin进行了 arp.setContainerFactory 操作,不同的 containerFactory 会生成不同类型的 map 对象。

     不过这个方法倒是可以考虑放开,只不过放开后就对封装性有影响,因为无法避免 jfinal 之外的代码对 columnTypeMap 进行修改,从而就有导致系统出错的可能。我考虑用 CPI 的方式开放出来。

引用来自“JFinal”的评论

    由于 columnTypeMap 没有在第一时间进行初始化,所以才有了 setColumnTypeMap 方法的存在

不用开放,columnTypeMap初始化成HashMap即可。

或者追加构造方法,直接将columnTypeMap做为参数,此方法可行性高些。。。

0
会炒饭的美工
会炒饭的美工
在jfinal2.2版本这个问题解决了吧?是怎么处理的?
返回顶部
顶部