2018-09-01 19:31

坚决从正面解决问题,又看了一会。

“String 到 Date 的类型转换错误还是没有找到源头,getCreateTime(...) 这个地方仅仅是异常抛出的地方,根本不是数据的源头 回复

JFinal 09-01 18:41
我很怀疑你的数据库字段本来就是 varchar,而你却误以为是 date/datetime”

这2个来自 非当事人视角的提示,非常关键。


来回从dateTime和varchar之间互相改,可以复现 错误提示
“java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
at com.jtn.bgj.common.model.base.BaseCategory.getCreateTime(BaseCategory.java:33)”。

只要能复现,说明 代码肯定哪里有问题。

然后看日志:
--------------------------------------------------------------------------------
Sql: select count(*) from brand
Sql: select * from brand order by id desc limit 0, 10
Sql: select *
from company
where id in(
1
, 2
)

Sql: select *
from company
where id in(
2
, 5
, 4
, 3
)
发现4个查询中,最后2个 批量in查询,竟然都是从 company。
终于定位到问题源头。


---------------------------------------
根本原因:Company表的createTime的确是 varchar的。(数据库设计时,默认 没有改)
category sql查询的 是 company表。(in查询 不太熟悉,搞定1个之后,复制粘贴的,表名没有改 )
---------------------------------------

波哥威武~
(*^__^*)
下班~

2018-09-01 19:09

感谢波哥(没错吧)没有放弃治疗我。搞定了。
Brand实体,有Company和Category,Company的createTime确实是 varchar,改为 datetime就好了。(MixedJson没有报错,FastJson报错)。

诡异的地方在于,category表的createTime 的确是 datetime,但是 为啥总是提示我 BaseCategory的createTime报错呢?
确认看了下日志,
2018-09-01 18:19:50
[ERROR]-[Thread: qtp1418334255-32]-[com.jfinal.core.ActionHandler.handle()]: /admin/brand/listData
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
at com.jtn.bgj.common.model.base.BaseCategory.getCreateTime(BaseCategory.java:33)

2018-09-01 18:22:49
[ERROR]-[Thread: qtp1418334255-29]-[com.jfinal.core.ActionHandler.handle()]: /admin/brand/listData
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
at com.jtn.bgj.common.model.base.BaseCategory.getCreateTime(BaseCategory.java:33)


2018-09-01 18:30:22
[ERROR]-[Thread: qtp1418334255-33]-[com.jfinal.core.ActionHandler.handle()]: /admin/brand/listData
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
at com.jtn.bgj.common.model.base.BaseCategory.getCreateTime(BaseCategory.java:33)

18:30去吃饭了,吃过饭后,把 Company表的 createTime从 varhcar改为 datetime,就可以了。

这个时候,我再从datetime改回varchar,提示报错:

2018-09-01 18:58:09
[ERROR]-[Thread: qtp1418334255-30]-[com.jfinal.core.ActionHandler.handle()]: /admin/brand/listData
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
at com.jtn.bgj.common.model.base.BaseCompany.getCreateTime(BaseCompany.java:65)

这个时候, 错误提示 就是准确的是“BaseCompany”。
我没有使用缓存。
很诡异~~~
--------------------------------------------------------------------------------
感谢波哥指点~~~

2018-09-01 18:31

public static void main(String[] args) {
Category category = new Category();
category.setCreateTime(new Date());
String s= JSON.toJSONString(category);
System.out.println(s);

Brand brand = new Brand();
brand.setCategory(category);
String s2= JSON.toJSONString(category);
System.out.println(s2);
}
输出结果,序列化成功
{"createTime":1535797596584}
{"createTime":1535797596584}

这个问题有点奇怪了,我自己再试试看看吧。

2018-09-01 18:08

Brand的Category的 createTime报的错。
com.jtn.bgj.common.model.base.BaseCategory.getCreateTime(BaseCategory.java:33)


@SuppressWarnings("serial")
public class Brand extends BaseBrand {

public Company getCompany() {
return super.get("company");
}

public void setCompany(Company company) {
super.put("company", company);
}

public Category getCategory() {
return super.get("category");
}

public void setCategory(Category category) {
super.put("category", category);
}

@Override
public String toString() {
return "Brand [toString()=" + super.toString() + "]";
}

}

2018-09-01 18:07

@JFinal 序列化麻烦再支持下哦。
public void configConstant(Constants me) {
me.setDevMode(p.getBoolean("devMode", true));
//me.setJsonFactory(MixedJsonFactory.me());
me.setJsonFactory(FastJsonFactory.me());
}
用MixedJsonFactory 序列化自定义的Result对象(里面有Brand列表,createTime是datetime)是ok的,但是换成FastJsonFactory在序列化的时候,就 报错了。

[ERROR]-[Thread: qtp1418334255-34]-[com.jfinal.core.ActionHandler.handle()]: /admin/brand/listData
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
at com.jtn.bgj.common.model.base.BaseCategory.getCreateTime(BaseCategory.java:33)
at com.alibaba.fastjson.serializer.ASMSerializer_5_Category.write(Unknown Source)
at com.alibaba.fastjson.serializer.ASMSerializer_3_Brand.write(Unknown Source)
at com.alibaba.fastjson.serializer.JSONSerializer.writeWithFieldName(JSONSerializer.java:304)
at com.alibaba.fastjson.serializer.JSONSerializer.writeWithFieldName(JSONSerializer.java:282)
at com.alibaba.fastjson.serializer.ASMSerializer_2_PageInfo.write(Unknown Source)
at com.alibaba.fastjson.serializer.JSONSerializer.writeWithFieldName(JSONSerializer.java:304)
at com.alibaba.fastjson.serializer.ASMSerializer_1_Result.write(Unknown Source)
at com.alibaba.fastjson.serializer.JSONSerializer.write(JSONSerializer.java:275)
at com.alibaba.fastjson.JSON.toJSONString(JSON.java:648)
at com.alibaba.fastjson.JSON.toJSONStringWithDateFormat(JSON.java:582)
at com.jfinal.json.FastJson.toJson(FastJson.java:44)
at com.jfinal.kit.JsonKit.toJson(JsonKit.java:28)
at com.jfinal.render.JsonRender.(JsonRender.java:125)
at com.jfinal.render.RenderFactory.getJsonRender(RenderFactory.java:103)
at com.jfinal.core.Controller.renderJson(Controller.java:1093)
at com.jtn.bgj._admin.brand.BrandAdminController.listData(BrandAdminController.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.jfinal.aop.Invocation.invoke(Invocation.java:73)
at com.jtn.bgj._admin.common.PjaxInterceptor.intercept(PjaxInterceptor.java:15)
at com.jfinal.aop.Invocation.invoke(Invocation.java:67)
at com.jfinal.core.ActionHandler.handle(ActionHandler.java:78)
at com.jfinal.plugin.druid.DruidStatViewHandler.handle(DruidStatViewHandler.java:81)
at com.jfinal.core.JFinalFilter.doFilter(JFinalFilter.java:73)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1307)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:453)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:560)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1072)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:382)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1006)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
at org.eclipse.jetty.server.Server.handle(Server.java:365)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:485)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:937)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:998)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:856)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:628)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:745)

2018-09-01 17:51

@JFinal 放到put里, 好了。确实 不需要再自定义属性。get和set方法就行了,用父类的attr统一维护 所有变量。
public void setCompany(Company company) {
//this.company = conpany;
super.put("company", company);
}

2018-09-01 17:49

@JFinal MixedJsonFactory.me(),Brand定义了 get和set也不行。 场景是这样的:品牌表,属于某个公司,数据库model只定义了 id,我手动再定义了 1个关联实体,company对象。 list查询之后,批量查询 公司,放到对应的 brand 里。
序列化确实没有 company 手动增加的属性,试试put吧。

2018-09-01 17:30

序列化方式使用的是 me.setJsonFactory(MixedJsonFactory.me());。
如果改为 FastJsonFactory.me(),Brand表创建时间 createTime 数据库明明是 datetime,却报错了
java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Date
at com.jtn.bgj.common.model.base.BaseCategory.getCreateTime(BaseCategory.java:33)

BaseCategory{
public java.util.Date getCreateTime() {
return get("createTime");
}
}

理论和实战 区别还真是大,遇到好多问题。
JFinal需要做几个项目才能搞定 所有问题。

2018-09-01 17:19

@JFinal 了解了。我的需求,jfinal自动支持了。

2018-09-01 15:22

JFinal3.4版本,已经支持 mysql user_id这种格式了吗

2018-09-01 15:11

用 MyMetaBuilder 继承一下 MetaBuilder , 然后覆盖掉其中的 buildAttrName() 方法,可以自由去控制生成的属性名

最后 generator.setMetaBuilder(new MyMetaBuilder()) 即可用上自己的实现?这样搞吗

2018-08-26 09:42

@a186chen 还没研究。这个涉及到 定时任务插件