此问题同#I9FTOI:[功能建议]: pageAs查询时VO中的字段映射,不应该处理嵌套的List对象。
当类中存在一个集合时,不应该往里面放入默认的元素。
假设这个属性是一个RelationOneToMany,当没有关联的元素时,会出现一个[{}]结构
以这张图为例 会出现
{
orderEmployeeList:[{}]
}
预期的结果应该是
{
orderEmployeeList:[]
}
如果查询不到结果 应该是空集合 或者null
变成了有一个空对象(字段全为null)的集合
1.8.7
[图片上传中…(image-CrBDLFtz74v4QSpKaIWq)]
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
麻烦 @Michael Yang @王帅 看下这个问题,这个问题的影响比较严重,所有嵌套的集合结构都存在bug,导致该功能大面积不可用。
请给出示例,以及错误信息。
这个问题比想象中的复杂,并不是原先想的原因。
问题出在 没有在resultMapping中对重复的列使用$进行区分。
现在我追踪到了TableInfo.buildResultMap.
create table person
(
id bigint primary key,
name varchar(200)
);
create table child
(
id bigint primary key,
person_id bigint,
student_id bigint,
name varchar(200)
);
create table student
(
id bigint primary key,
person_id bigint
);
```java
public class Child extends BaseEntity{
Long personId;
Long studentId;
String name;
}
public class Person extends BaseEntity{
String name;
@RelationOneToMany(targetTable = "student", targetField = "personId")
List<Student> students ;
}
public class Student extends BaseEntity{
// String name;
Long personId;
@RelationOneToOne(targetTable = "child", targetField = "studentId")
Child child;
}
public static void main(String[] args) {
final ConfigurableApplicationContext context = SpringApplication.run(Demo7Application.class, args);
//开启审计功能
AuditManager.setAuditEnable(true);
//设置 SQL 审计收集器
MessageCollector collector = new ConsoleMessageCollector();
AuditManager.setMessageCollector(collector);
final PersonMapper mapper =(PersonMapper) Mappers.ofEntityClass(Person.class);
final Person selectPerson = mapper.selectOneById(1L);
System.out.println(selectPerson);
}
可以看到 当孙子层级中出现了祖先层级中的同名字段时,可以复现这个问题(但是父辈中不存在这个属性)
即:这个属性在第一级和第三级存在 但是在第二级不存在,可能因为中断了,导致没有在ResultMap中拼接上$
我对这块逻辑不是很清楚,但是我觉得问题可能出在这里existedColumns的收集上
我创建一个仓库 里面现成的代码可以用于复现这个问题
@王帅
https://gitee.com/swqxdba/flex-bug-report
我提供了测试demo仓库,测试仓库中的代码打个断点就可以复现
这里mapper.selectOneById
没有使用withRelation,显然这里的student应该是空集合或者null
private void collectNestedColumnsDfs(Class<?> root,List<String> collected,Set<Class<?>> existClasses){
if(existClasses.contains(root)){
return;
}
existClasses.add(root);
final TableInfo tableInfo = TableInfoFactory.ofEntityClass(root);
collected.addAll(Arrays.asList(tableInfo.allColumns));
if(tableInfo.collectionType!=null){
for (Class<?> entityType : tableInfo.collectionType.values()) {
collectNestedColumnsDfs(entityType,collected,existClasses);
}
}
if(tableInfo.associationType!=null){
for (Class<?> entityType : tableInfo.associationType.values()) {
collectNestedColumnsDfs(entityType,collected,existClasses);
}
}
}
public ResultMap buildResultMap(Configuration configuration) {
// 所有的嵌套类对象引用
List<String> collector = new LinkedList<>();
collectNestedColumnsDfs(this.entityClass,collector,new HashSet<>());
Stream<String> nestedColumns =collector.stream();
}
@王帅 看看这个实现
登录 后才可以发表评论