繁体   English   中英

如何通过oData创建新的子节点实体而不更新或创建根节点

[英]How to create a new Child node entity via oData without updating or creating the root node

我已经在S / 4HANA Cloud中创建了一个自定义业务对象,它包含一个父节点和一个子节点,并且还为S / 4HANA自定义OData服务生成了Java VDM。 我将其与SAP Cloud Platform SDK结合在一起用于服务开发(我现在无法找到其“ SAP帮助”页面)。

该方案将能够仅将新的子节点添加到现有的根节点。

当我尝试使用其他字段值对ParentEntitySet()/ childNavigation进行POST操作时,收到错误消息“无效的方法调用:在非根实体YY1_CHILD_ENTITY上调用了“ CREATE”方法。

如何解决此错误?

更新:

如我所述,旧代码导致了错误

@Create(serviceName = "CrudService", entity = "ChildEntitySet", sourceEntity = "ParentEntitySet")
    public CreateResponse createABC(CreateRequest createRequest) {

        EntityData entity = createRequest.getData();

        LeaveRequest response;
        try {
            response = new CreateChildCommand(new ErpConfigContext(), new DefaultService(), entity)
                    .execute();
        } catch (HystrixBadRequestException e) {
            return CreateResponse.setError(new ErrorResponseImpl(400, null, e.getMessage(), e.getCause(), null));
        }

        CreateResponse readResponse = CreateResponse.setSuccess().setData(response).response();

        return readResponse;
    }

新代码:错误消失了,但是当我尝试通过导航发布子实体时出现了新错误。

Inavalid Entity name: No entity with name ParentClass(guid'<parentKey>')/to_ChildEntity in the OData service

但是,当我使用与上面相同的url进行导航查询时,它运行良好。 仅使用导航创建会出现此问题。

@Create(serviceName = "CrudService", entity = "ChildEntitySet", sourceEntity = "ParentEntitySet")
    public CreateResponse createChild(CreateRequest createRequest) {

        EntityData entity = createRequest.getData();

        String parentKey = (String) createRequest.getSourceKeys().get(<parentKey>);

        ChildClass response = new ChildClass();
        Map<String, Object> childEntity = new HashMap<>();
        try {
            childEntity = entity.asMap();
            response.setParentKey((String) entity.asMap().get(<parentKey>));
            response.setText((String) entity.asMap().get("Text"));
            response.setCreatedBy((String) entity.asMap().get("CreatedBy"));
            response.setCreatedOn((Calendar) entity.asMap().get("CreatedOn"));

            ParentClass parent = new ParentReadByKeyCommand(new ErpConfigContext(), parentKey)
                    .execute();
            parent.createChildEntity(childEntity);
            return CreateResponse.setSuccess().setData(response).response();
        } catch (Exception e) {
            // Return an instance of QueryResponse containing the error in case of failure
            ErrorResponse errorResponse = ErrorResponse.getBuilder().setMessage(e.getMessage())
                    .setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR).setCause(e).response();
            return CreateResponse.setError(errorResponse);
        }
    }

下面的方法属于ParentClass

public ChildClass createChildEntity(Map<String, Object> childEntity) throws ODataException {
        if (erpConfigContext == null) {
            throw new ODataException(ODataExceptionType.OTHER, "Failed to fetch related objects of type ChildClass.",
                    new IllegalStateException(
                            "Unable to execute OData query. The entity was created locally without an assigned ERP configuration context. This method is applicable only on entities which were retrieved or created using the OData VDM."));
        }
        final StringBuilder odataResourceUrl = new StringBuilder(getEntityCollection());
        odataResourceUrl.append("(");
        odataResourceUrl.append(ODataTypeValueSerializer.of(EdmSimpleTypeKind.Guid).toUri(<parentKey>));
        odataResourceUrl.append(")/");
        odataResourceUrl.append("to_ChildEntity");
        final ODataCreateRequestBuilder builder = ODataCreateRequestBuilder
                .withEntity(getEndpointUrl(), odataResourceUrl.toString()).withBodyAsMap(childEntity);
        final ODataCreateRequest query = builder.build();
        final ODataCreateResult result = query.execute(erpConfigContext);
        final ChildClass entity = result.as(ChildClass.class);
        entity.setErpConfigContext(erpConfigContext);
        return entity;
    }

我正在使用

<parent>
        <groupId>com.sap.cloud.servicesdk.prov</groupId>
        <artifactId>projects-parent</artifactId>
        <version>1.19.0</version>
    </parent>

<dependencies>
        <dependency>
            <groupId>com.sap.cloud.s4hana</groupId>
            <artifactId>sdk-parent</artifactId>
            <version>1.11.1</version>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>com.sap.cloud.s4hana</groupId>
            <artifactId>s4hana-all</artifactId>
            <!-- <version>1.11.1</version> -->
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

某些OData API仅允许通过根实体创建子实体。

但是,当前,S / 4HANA Cloud SDK的VDM不支持此功能。

如果有更新,我将更新此答案。

更新:从2.4.1版开始,如果使用S / 4 HANA Cloud SDK,则现在可以将实体创建为另一个实体的子代。

该代码可能看起来像这样:

new YourCustomService()
    .createChildEntity(childEntity)
    .asChildOf(parentEntity, ParentEntity.TO_CHILD_ENTITY)
    .execute();

或者使用SDK提供的BusinessPartner的更实际的示例:

new DefaultBusinessPartnerService().createBusinessPartnerAddress(someAddress)
    .asChildOf(
        someBusinessPartner,
        BusinessPartner.TO_BUSINESS_PARTNER_ADDRESS
    )
    .execute();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM