问题描述

在使用hibernate拼接hql时,新增字段竟然没有出现在构造方法中(下面是简化版,真实情况要复杂的多)

//实体类

public class Tmd {

private String CBh;

private Integer NSjzzaqxx;

//private String CAjysly;//新加字段

public static final String cTmdConstructorFields = "(CBh,NSjzzaqxx)";

//public static final String cTmdConstructorFields = "(CBh,NSjzzaqxx,CAjysly)";//新增字段添加进构造器

//......Constructos......

//......getter/setter......

}

//工具类

public class DatamodelUtils{

public static String CTmdConstructorFields = Tmd.cTmdConstructorFields;

}

通过Hibernate查询对象,这里使用select new 的方式,SQL里的对象有多少个参数,实体类也要有数据类型和参数个数一致的构造器

StringBuilder hql = new StringBuilder();

hql.append("select new ").append("com.luo.Tmd").append(DatamodelUtils.CTmdConstructorFields);

服务器上跑的就是这个,因为需求,我在Tmd新增了一个字段CAjysly,构造器也进行了修改,最后我把修改后的 Tmd.class 放到测试环境上的工作目前work中,重启项目,报错

Caused by: org.springframework.orm.hibernate3.HibernateQueryException: Unable to locate appropriate constructor on class .....

看了日志,发现没有我新增的字段,最后拼接的hql是这样的

select new com.luo.Tmd(CBh,NSjzzaqxx)

为啥我新增的字段没有呢?

原因分析:

是不是新增了字段后,代码没有编译上

随后我马上到生成环境上查看Tmd.class,看看是不是我没有编译上,随后使用arthas去看了Tmd.class,发现新增字段是存在的,构造器里面也有,此时的我很懵逼

//修改之前的DatamodelUtils.class

public static String CTmdConstructorFields = "(CBh,NSjzzaqxx)";

然后看看DatamodelUtils.CTmdConstructorFields 值,发现竟是 "(CBh,NSjzzaqxx)",还是原来的值,此时大概就明白了,我出的替换文件仅仅是Tmd.class,但是DatamodelUtils.class还是原来的,并没有重新加载,因为服务器根本没有检测到DatamodelUtils的变化

解决方案:

对DatamodelUtils重新进行编译,发布到测试环境上

反思总结:

在出增量替换文件的情况下,对于常量的修改,要切记使用到常量的地方,都要重新进行编译,然后发布

推荐文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。