当前位置: 首页 > 知识库问答 >
问题:

QueryDsl:来自oneTo的空实体与投影bean关联。

羊禄
2023-03-14

所以我想在我的项目中使用投影bean来优化加载时间(以避免获得无用的数据……)。

我有两个实体:父母-

在我的数据库中,我有:

  • 父 1 与子 1 和子 2
  • 父母2机智的孩子

我想在一个请求中得到父母和孩子,所以首先我这样做了:

final JPAQueryBase<?> query = createQuery();

final QParent qParent = QParent.parent;
final QChild qChild = QChild.child;

Map<Long, Parent> transform = query.from(qParent)
        .leftJoin(qParent.children, qChild)
        .transform(GroupBy.groupBy(qParent.id)
                .as(Projections.bean(Parent.class,
                        qParent.id,
                        qParent.name,
                        GroupBy.set(qChild).as(qParent.children))));

final List<Parent> parents = new ArrayList<Parent>(transform.values());

它发挥了巨大的作用,结果如下:

[
    Parent: {
        id: 1,
        name: "parent1",
        children: [
            Children: {
                id: 1,
                name: "child1",
                otherAttr: //loaded
            },
            Children: {
                id: 2,
                name: "child2",
                otherAttr: //loaded
            }
        ],
        otherAttr: null
    },
    Parent: {
        id: 2,
        name: "parent2",
        children: [], //size: 0
        otherAttr: null
    }
]

但我不想从子实体加载“其他属性”。因此,我使用子实体的投影 bean 执行了此查询:

final JPAQueryBase<?> query = createQuery();

final QParent qParent = QParent.parent;
final QChild qChild = QChild.child;

Map<Long, Parent> transform = query.from(qParent)
        .leftJoin(qParent.children, qChild)
        .transform(GroupBy.groupBy(qParent.id)
                .as(Projections.bean(Parent.class,
                        qParent.id,
                        qParent.name,
                        GroupBy.set(Projections.bean(Child.class,
                                qChild.id,
                                qChild.name))
                                .as(qParent.children))));

final List<Parent> parents = new ArrayList<Parent>(transform.values());

通过这个查询,我可以完全控制要选择的属性。但当父级没有子级时,会发生奇怪的事情:子级列表中存在一个所有属性都设置为null的Child对象,如下所示:

[
    Parent: {
        id: 1,
        name: "parent1",
        children: [
            Children: {
                id: 1,
                name: "child1",
                otherAttr: null
            },
            Children: {
                id: 2,
                name: "child2",
                otherAttr: null
            }
        ],
        otherAttr: null
    },
    Parent: {
        id: 2,
        name: "parent2",
        children: [ //size: 1
            Children: {
                    id: null,
                    name: null,
                    otherAttr: null
                }
        ],
        otherAttr: null
    }
]

这是一个错误吗?如果不是,我做错了什么??

共有1个答案

柯昆杰
2023-03-14

我自己遇到了这个问题,我将把GitHub第1677期的答案放在这里以供将来参考。单个投影必须用skipNulls()标记:

Map<Long, Parent> transform = query.from(qParent)
    .leftJoin(qParent.children, qChild)
    .transform(GroupBy.groupBy(qParent.id)
            .as(Projections.bean(Parent.class,
                    qParent.id,
                    qParent.name,
                    GroupBy.list(Projections.bean(Child.class,
                            qChild.id,
                            qChild.name,
                            Projections.bean(qSubChild.class,
                                    qSubChild.id,
                                    qSubChild.name).skipNulls()
                                    .as(qChild.subChild)).skipNulls())
                            .as(qParent.children))));
 类似资料:
  • 给定这个查询: 问题是查询只在parentDevice不为空时返回设备。为什么?如何拿回任何价值?如果我从投影中取出qdevice.parentdevice,结果是好的。 QueryDsl版本为3.2.0

  • 这只有两种方式: 具有qdoc.id:存在,为空 不带qdoc.id:为空,存在 我已经检查过的内容:当我在Postgres客户机中运行Hibernate查询时,它总是带来字段。Bot在这两种情况下都存在。

  • 但是如果可能的话,我想避免这种情况,因为它迫使我定义n个构造函数,为我在投影中想要的n个字段组合定义n个构造函数。

  • 我正在考虑使用DTO投影--我有两个具有一对多关系的实体(EntityOne的一个实例链接到EntityTwo的多个实例),我希望将结果作为一个新的DTO对象返回--我目前正在尝试的是: 其中MyDtoObject如下所示: 但是,这带来的MyDtoObjects比预期的要多得多,而且看起来每个对象都只包含一个entityTwo对象,而不是集合。 如何指示queryDSL创建具有多个entityT

  • 问题内容: 我很难获得标准表达式的结果相关实体对象的列表。我有两个具有多对多关系的对象,例如ObjectA <-> ObjectB,其中ObjectA的单个实例可以绑定到ObjectB的多个实例,而ObjectB的实例可以绑定到ObjectA的多个实例。该关系存储在您的典型联接表中,但是由于遗留原因,对象模型是这样的,因此ObjectB无法直接知道其与ObjectA的关系。我正在尝试创建一个条件表

  • 我试图使用一个投影来从一个实体中提取数据,它有一些关系。然而。投影上的构造函数接受三个参数;一个集合,整数和另一个整数。如果没有这个集合作为参数,这一切都很好,但是一旦我添加了这个集合,我就开始得到SQL语法查询错误。 这里有一个我正在使用的例子... 下面是我正在使用的查询(不完全相同,因为这是我正在处理的问题的简化版本).... 所以,我想我的主要问题是,我如何将一个集合作为一个对象包含在投影