3.6 Model 新增 findByIds 后,原(3.5) findById 行为不一致

JFinal 3.6 在 Model 中新增了 findByIds 方法

public M findByIds(Object... idValues) {
   return findByIdLoadColumns(idValues, "*");
}

同时将原有的 3.5 版的 findById 行为改了

3.5 findById 代码如下

public M findById(Object... idValues) {
   return findByIdLoadColumns(idValues, "*");
}

3.6 findById 代码如下

public M findById(Object idValue) {
   return findByIdLoadColumns(new Object[]{idValue}, "*");
}

这样修改后,从 3.5 升级到 3.6时原来的 findById 方法行为就不一致了,请大神指导一下

评论区

JFinal

2019-04-23 08:31

如果是单主键,用原来的 findById 即可, 如果是多主键则要使用 findByIds

这个改变只影响多主键

li7

2019-04-23 09:02

@JFinal 调整后,对于这两个方法的用途我没有疑问。只是觉得这样调整后,版本升级会比较麻烦。不敢升,不知道会不会有其他类似的情况。这样的调整编译不报错,没警告,只有覆盖测试...

JFinal

2019-04-23 09:27

@li7 对于原有代码中只有一个主键的用法完全没有影响

对于原有代码中有多个主键的用法,eclipse 会有错误提示,升级也很安全

唯一的风险是打在 jar 中的多主键用法,eclipse 没有提示,需要在运行时才能发现问题

综上,重点在于注意 jar 中的多主键用法,总体来说升级还是很方便的

li7

2019-04-27 10:13

不好意思,这几天忘了。我是用的IDEA,升级到3.6之后,没有错误提示,代码编译不报错,也没有警告。整个工程可以正常运行。就是在用 3.6 版的 findById 时,将我传入的 idValue 转成了 new Object[]{idValue} 导致一直查不到数据。所以我才说 3.5 到 3.6 的这个升级,改变了 findById 的行为,导致升级时必须要修改所有的 findById 相关的代码

JFinal

2019-04-27 10:34

@li7 贴一点代码出来看看,应该不会的

li7

2019-04-28 07:05

应该是这样的,3.5版里面,有两个 findById 方法,接受两种类型的参数

public M findById(Object idValue) {
return findByIdLoadColumns(new Object[]{idValue}, "*");
}

public M findById(Object... idValues) {
return findByIdLoadColumns(idValues, "*");
}

我的代码里面用了 findById(Object... idValues) 这个。
但是从 3.6 开始, findById(Object... idValues) 这个方法又正好被删除了。
由于 findById(Object idValue) 这个方法还在,所以编译不报错,没警告。
但是 findById 里面的行为已经变了,导致查不到数据,执行也不报错。
就是这样了。

JFinal

2019-04-28 09:22

@li7 你的代码里面用了 findById(Object... idValues) 这个,在这个条件下,有两种情况:

1:你的代码确实有两个或更多主键,那么形如:
findById(id1, id2);
这种情况升级到 3.6 以后, eclipse 会提示错误,因为 3.6 的 findById 只接受一个参数,形如:
findById(id1);

2:你的代码确实只有一个主键,形如:
findById(id1);
这种情况,升级后完全没有影响,因为 findById 就是针对一个主键的功能,恰好吻合

因此,你上一个回复的问题肯定是不存在的。

li7

2019-04-28 13:24

主要问题是我是这样用的

li7

2019-04-28 13:24

public M findByPk(){
Table table = _getTable();
String[] pKeys = table.getPrimaryKey();

if( pKeys == null ){
log.debug(table.getName() + " 未找到主键字段");
pKeys = new String[0];
}
Object[] vals = new Object[pKeys.length];

for (int i=0; i vals[i] = get(pKeys[i]);
}

return findById(vals);
}

JFinal

2019-04-28 14:06

@li7 这个是你自己封装过,改进起来更容易,只需要将最后一行代码:
return findById(vals)
改成:
if (vals.length == 1) {
return findById(vals[0]);
} else {
return findByIds(vals);
}

li7

2019-04-28 14:21

嗯嗯,确实这个改动确实很容易。只是我发现这个问题才知道是版本升级导致的。所以我就觉得这样的版本升级可以避免,就比如从 afterJFinalStart 改为 onStart,就完全不影响旧的代码的运行。
个人想法。就是在小版本升级版本的时候,能尽量保障旧代码的运行不受影响

JFinal

2019-04-28 15:19

@li7 这个改动是被逼的,因为3.6 之前基于 JDK 1.6 编译级别没任何问题,而 3.6 版本基于 JDK 1.8 编译级别以后出现类型转换错误

而出现错误的地方 jfinal 完全没动过代码,本质是 JDK 的兼容性问题

为了将升级 JDK 的问题损失降到最低,才添加了 findByIds