CAP:无法通过 CQL 查询获取 com.sap.cds.ql.Predicate 中复合实体的实体字段

问题描述 投票:0回答:1

我有一个名为 ComplaintTypeConfigurations 的数据库实体,如下所示。

entity ComplaintTypeConfigurations : cuid, managed {
    identifier                       : DataType.Identifier;
    complaintCategory                : ComplaintCategory;
    code                             : DataType.Code;
    description                      : localized DataType.Description;
    individualComplaintType          : DataType.Flag default false;
    itemCategory                     : ItemCategory;
    complaintTypeToSalesAreaMappings : Composition of many ComplaintTypeToSalesAreaMappings
                                           on complaintTypeToSalesAreaMappings.complaintTypeConfiguration = $self;
    numberRange                      : NumberRange; //deprecated
    isActive                         : Boolean default true;
    currentNumber                    : DataType.CurrentNumber; //deprecated
}

这里我们有一个与 complaintTypeToSalesAreaMappings 的复合关系,它下面有

salesOrganization
distributionchannel
division
字段,如下所示。

entity ComplaintTypeToSalesAreaMappings : cuid, managed {
    salesOrganization          : SalesOrganization;
    distributionChannel        : DistributionChannel;
    division                   : Division;
    complaintTypeConfiguration : ComplaintTypeConfiguration;
}

现在我想使用如下所示的谓词来查询 sales/distribution/division


        Predicate predicateSalesArea = CQL.get(ComplaintTypeToSalesAreaMappings.SALES_ORGANIZATION_ID).eq(salesOrganization)
                .and(CQL.get(ComplaintTypeToSalesAreaMappings.DISTRIBUTION_CHANNEL_ID).isNull()
                        .and(CQL.get(ComplaintTypeToSalesAreaMappings.DIVISION_ID).isNull()))
                .or(CQL.get(ComplaintTypeToSalesAreaMappings.SALES_ORGANIZATION_ID).eq(salesOrganization)
                        .and(CQL.get(ComplaintTypeToSalesAreaMappings.DISTRIBUTION_CHANNEL_ID).eq(distributionChannel)
                                .and(CQL.get(ComplaintTypeToSalesAreaMappings.DIVISION_ID).isNull())))
                .or(CQL.get(ComplaintTypeToSalesAreaMappings.SALES_ORGANIZATION_ID).eq(salesOrganization)
                        .and(CQL.get(ComplaintTypeToSalesAreaMappings.DISTRIBUTION_CHANNEL_ID).eq(distributionChannel)
                                .and(CQL.get(ComplaintTypeToSalesAreaMappings.DIVISION_ID).eq(division))));
        
        Predicate predicate = CQL.get(ComplaintTypeConfigurations.IS_ACTIVE).eq(true)
                  .and(CQL.get(ComplaintTypeConfigurations.COMPLAINT_CATEGORY_CODE).eq(complaintCategoryCode))
                  .and(CQL.get(ComplaintTypeConfigurations.COMPLAINT_TYPE_TO_SALES_AREA_MAPPINGS).isNull()).or(predicateSalesArea);
        
    if(code!=null || description!=null) {
            
            predicate.and(CQL.get(ComplaintTypeConfigurations.CODE).contains(code).and(CQL.get(ComplaintTypeConfigurations.DESCRIPTION).contains(description)));
        }
            
            
        CqnSelect select=Select.from(ComplaintTypeConfigurations_.class)
                        .columns(a->a.ID(),b->b.code(),c->c.description(),
                                e->e.complaintTypeToSalesAreaMappings().salesOrganization_ID(),
                                f->f.complaintTypeToSalesAreaMappings().distributionChannel_ID(),
                                g->g.complaintTypeToSalesAreaMappings().division_ID(),
                                h->h.individualComplaintType(),
                                i->i.itemCategory_ID()).where(predicate);

filteredResult=db.run(select);

当我运行此查询时,出现如下错误。

No element with name 'salesOrganization_ID' in 'CustomerConfigurationService.ComplaintTypeConfigurations' (service 'PersistenceService$Default', event 'READ', entity 'CustomerConfigurationService.ComplaintTypeConfigurations')
    at com.sap.cds.services.impl.ServiceImpl.dispatch(ServiceImpl.java:256) ~[cds-services-impl-2.10.1.jar:na]
    at com.sap.cds.services.impl.ServiceImpl.emit(ServiceImpl.java:177) ~[cds-services-impl-2.10.1.jar:na]
    at com.sap.cds.services.ServiceDelegator.emit(ServiceDelegator.java:33) ~[cds-services-api-2.10.1.jar:na]
    at com.sap.cds.services.utils.services.AbstractCqnService.run(AbstractCqnService.java:53) ~[cds-services-utils-2.10.1.jar:na]
    at com.sap.cds.services.utils.services.AbstractCqnService.run(AbstractCqnService.java:43) ~[cds-services-utils-2.10.1.jar:na]
    at com.sap.ic.cmh.configuration.persistency.ComplaintTypeConfigurationDao.getAllComplaintsWithWildCharacter(ComplaintTypeConfigurationDao.java:179) ~[classes/:na]
    at jdk.internal.reflect.GeneratedMethodAccessor33.invoke(Unknown Source) ~[na:na]

我无法获取复合实体字段,如何使用谓词来实现此目的。 有人可以帮我吗?

但是我可以使用 CQN 查询来实现此目的,如下所示。

        filteredResult = db
                .run(Select.from(ComplaintTypeConfigurations_.class)
                        .columns(a->a.ID(),b->b.code(),c->c.description(),
                                e->e.complaintTypeToSalesAreaMappings().salesOrganization_ID(),
                                f->f.complaintTypeToSalesAreaMappings().distributionChannel_ID(),
                                g->g.complaintTypeToSalesAreaMappings().division_ID(),
                                h->h.individualComplaintType(),
                                i->i.itemCategory_ID())
                        .where(d->d.isActive().eq(true).and(d.complaintCategory_code().eq(complaintCategoryCode).and(d.code().contains(code).or(d.description().contains(description))).and(not(d.complaintTypeToSalesAreaMappings().exists())
                                .or(d.complaintTypeToSalesAreaMappings().salesOrganization_ID().eq(salesOrganization)
                                        .and(d.complaintTypeToSalesAreaMappings().distributionChannel_ID().isNull()
                                                .and(d.complaintTypeToSalesAreaMappings().division_ID().isNull())))
                                .or(d.complaintTypeToSalesAreaMappings().salesOrganization_ID().eq(salesOrganization)
                                        .and(d.complaintTypeToSalesAreaMappings().distributionChannel_ID().eq(distributionChannel)
                                                .and(d.complaintTypeToSalesAreaMappings().division_ID().isNull())))
                                .or(d.complaintTypeToSalesAreaMappings().salesOrganization_ID().eq(salesOrganization)
                                        .and(d.complaintTypeToSalesAreaMappings().distributionChannel_ID().eq(distributionChannel)
                                                .and(d.complaintTypeToSalesAreaMappings().division_ID().eq(division))))))));

但对于我的场景,我需要根据某些条件修改查询,因此使用上面的查询,我最终会得到多个 if else 块,其中的查询几乎相同,但对字段进行了轻微修改。因此,我们决定使用谓词。但我们无法实现这一目标。

java spring sap-cap
1个回答
0
投票

根据错误消息,谓词中似乎缺少一个级别。根据错误消息,在 ComplaintTypeConfigurations 中搜索名为

salesOrganization_ID
的字段,该字段实际上位于 ComplaintTypeToSalesAreaMappings 中。如果我查看您共享的 CQN 查询,它显示在 ComplaintTypeToSalesAreaMappings:
salesOrganization_ID
中搜索
d.complaintTypeToSalesAreaMappings().salesOrganization_ID()
。因此,查询是针对 ComplaintTypeConfigurations_.class,但您必须向下一级。

如果您查看 CQL 的 Java 文档.get,我认为您可以使用两种类型的参数化。一种是使用 String 参数,您可以在其中用点分隔元素名称,或者可以将列表传递给它。我还没有尝试过,但我在想这样的事情:

CQL.get(ComplaintTypeConfigurations.COMPLAINT_TYPE_TO_SALES_AREA_MAPPINGS + "." + ComplaintTypeToSalesAreaMappings.SALES_ORGANIZATION_ID)

你可以尝试一下吗?

© www.soinside.com 2019 - 2024. All rights reserved.