jfinal从3.3升级到3.5后出现的类型转换bug

方法:boolean delete(String tableName, String primaryKey, Record record)

3.3版本

public boolean delete(String tableName, String primaryKey, Record record) {
    String[] pKeys = primaryKey.split(
",");
    if
(pKeys.length <= 1) {
       
return this.deleteById(tableName, primaryKey, record.get(primaryKey));
    
} else {
       
this.config.dialect.trimPrimaryKeys(pKeys);
        
Object[] idValue = new Object[pKeys.length];

        for
(int i = 0; i < pKeys.length; ++i) {
            idValue[i] = record.get(pKeys[i])
;
            if
(idValue[i] == null) {
               
throw new IllegalArgumentException("The value of primary key \"" + pKeys[i] + "\" can not be null in record object");
            
}
        }

       
return this.deleteById(tableName, primaryKey, idValue);
    
}
}

 

3.5版本

public boolean delete(String tableName, String primaryKey, Record record) {
    String[] pKeys = primaryKey.split(
",");
    if
(pKeys.length <= 1) {
       
return this.deleteById(tableName, primaryKey, (Object[])record.get(primaryKey));
    
} else {
       
this.config.dialect.trimPrimaryKeys(pKeys);
        
Object[] idValue = new Object[pKeys.length];

        for
(int i = 0; i < pKeys.length; ++i) {
            idValue[i] = record.get(pKeys[i])
;
            if
(idValue[i] == null) {
               
throw new IllegalArgumentException("The value of primary key \"" + pKeys[i] + "\" can not be null in record object");
            
}
        }

       
return this.deleteById(tableName, primaryKey, idValue);
    
}
}

throw:********** cannot be cast to [Ljava.lang.Object;

评论区

JFinal

2018-12-18 16:31

这个地方 jfinal 没有改变过,是 Java 8 对于这类参数的行为有变化,看一下源码可知道这里并没有变过

解决办法如下:
1: 做一个 public MyDbPro extends DbPro ,并且覆盖掉你碰到问题的这个 delete 方法,将其中的:
return deleteById(tableName, primaryKey, record.get(primaryKey))
改成下面的代码:
return deleteById(tableName, primaryKey, (Object)record.get(primaryKey))

2:做一个public class MyDbProFactory implements IDbProFactory,内部代码如下:
public DbPro getDbPro(String configName) {
return new MyDbPro(configName);
}

3:将你自己的 MyDbPro 切换上去:
activeRecordPlugin.setDbProFactory(new MyDbProFactory());

记得搞定后回来再反馈一下,然后我可以将这个功能做到 jfinal 3.6 中去,感谢反馈

JFinal

2018-12-18 16:34

如果上面那行代码还有问题,改成下面这种:
Object para = record.get(primaryKey);
return deleteById(tableName, primaryKey, para);

本质就是让 java 8 能正确识别参数,不去将 para 当成数组,而是当成 Object

sourceTT

2018-12-19 13:18

@JFinal 我现在就是用的这种方法,也看了源码发现并没有什么差别。然后看了编译后的文件才发现的问题,意识到了是Java导致的编译问题。

这里提出来只是做个记录和反馈,避免后续代码出现类似的错误,编程语言更新是容易出现各种问题的。

JFinal

2018-12-25 14:35

@sourceTT 你那里具体解决的代码能贴出来不? 确保 jfinal 3.6 对这里的改进是万无一失的,谢谢你的贡献

sourceTT

2018-12-25 16:14

@JFinal Db.deleteById(tableName,primaryKey, (Object) record.get(ID));
我现在是这样使用的
编译后就变成这样了 new Object[]{record.get(ID)}

JFinal

2019-01-29 21:42

这个问题得到了确证,是 JKD 1.8 的问题,目前 jfinal 3.6 已经对此做了适配性调整,但 jfinal 3.6 要过几天才能发布

目前建议的解决办法如下:
1:改用 deleteById,例如:Db.deleteById("user", "id", record.getInt("id"));
2:使用线上最新版本: git@gitee.com:jfinal/jfinal.git
线上最新版本使用下面的办法安装到本地:
git clone git@gitee.com:jfinal/jfinal.git
cd jfinal
mvn clean install
安装完成后,项目中的 3.5 版本号改成 3.6-SNAPSHOT

以上两个办法,两者选其一就可以。

Db 工具类中有很多可选方法可以使用,有两个方法会由 JDK 1.8 产生问题,换成别的方法代替就可以解决了。

过几天会发布 jfinal 3.6

JFinal

2019-01-29 21:43

这里还有一个类似的贴子:
http://www.jfinal.com/feedback/3638

热门反馈

扫码入社