Uploaded image for project: 'OASIS Open Data Protocol (OData) TC'
  1. OASIS Open Data Protocol (OData) TC
  2. ODATA-1450

Key with PropertyRef using navigation path incompatible with Protocol 11.4.2 "Create an Entity"

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: New
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: V4.01_OS
    • Fix Version/s: V4.01_ERRATA01
    • Component/s: CSDL XML, Protocol
    • Labels:
      None
    • Environment:

      Proposed

    • Proposal:
      Hide

      Disallow PropertyRef using a navigation path. (in V4.02)

      Or, add a clarification that bind operations must be used to indicate an entity's key for create/update and that inline relationships will otherwise be treated as deep insert/update. (in V4.01 Errata 01)

      Show
      Disallow PropertyRef using a navigation path. (in V4.02) Or, add a clarification that bind operations must be used to indicate an entity's key for create/update and that inline relationships will otherwise be treated as deep insert/update. (in V4.01 Errata 01)

      Description

      Consider this CSDL.

      <?xml version="1.0" encoding="utf-8"?>
      <edmx:Edmx Version="4.01" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://docs.oasis-open.org/odata/ns/edmx http://docs.oasis-open.org/odata/odata/v4.0/os/schemas/edmx.xsd http://docs.oasis-open.org/odata/ns/edm http://docs.oasis-open.org/odata/odata/v4.0/os/schemas/edm.xsd">
          <edmx:DataServices>
              <Schema Namespace="example" xmlns="http://docs.oasis-open.org/odata/ns/edm" Alias="Self">
                  <EntityType Name="Customer">
                      <Key>
                          <PropertyRef Name="ID"/>
                      </Key>
                      <Property Name="ID" Type="Edm.Int32" Nullable="false"/>
                      <NavigationProperty Name="Photo" Type="Self.CustomerPhoto" Partner="Customer">
                          <OnDelete Action="Cascade"/>
                      </NavigationProperty>
                  </EntityType>
                  <EntityType Name="CustomerPhoto">
                      <Key>
                          <PropertyRef Name="Customer/ID" Alias="CustomerID"/>
                      </Key>
                      <Property Name="Photo" Type="Edm.Stream" Nullable="false"/>
                      <NavigationProperty Name="Customer" Type="Self.Customer" Nullable="false"/>
                  </EntityType>
                  <EntityContainer Name="CustomerService">
                      <EntitySet Name="Customers" EntityType="Self.Customer">
                          <NavigationPropertyBinding Path="Photo" Target="CustomerPhotos"/>
                      </EntitySet>
                      <EntitySet Name="CustomerPhotos" EntityType="Self.CustomerPhoto">
                          <NavigationPropertyBinding Path="Customer" Target="Customers"/>
                      </EntitySet>
                  </EntityContainer>
              </Schema>
          </edmx:DataServices>
      </edmx:Edmx>
      

      If a client sends this request:

      POST /CustomerPhotos
      {"Customer":{"ID":123}}

      then per Protocol 11.4.2 "Create an Entity":

      The entity representation MAY include references to existing entities as well as content for new related entities, but MUST NOT contain content for existing related entities.

      ... the above POST request MUST be interpreted as a deep insert. The client cannot portably create a CustomerPhoto (except via a bind operation) as any attempt to specify its key (via the customer it relates to) will be interpreted as a deep insert.

      If we were to relax the language in section 11.4.2 to allow an interpretation of relating a CustomerPhoto to an existing Customer (rather than also creating the Customer by deep insert), then the specification is now ambiguous in regard to the correct interpretation of the above example payload.

      Similar issues apply to 11.4.3.1 "Update Related Entities When Updating an Entity"

      If a nested entity has the same id or key fields as an existing entity, the existing entity is updated according to the semantics of the PUT or PATCH request.

      Using the same payload for updating an existing CustomerPhoto by PUT (in an attempt to link the photo to a different Customer) would be interpreted as a deep update to PUT the newly related customer (clearing its non-key properties, if any).

      The key point of discussing the issue is to work out how to discourage implementers from treating inline relationships (with only the related entity's key) as a substitute for bind operations while at the same time not implementing bind operations the standard way.

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              evan.ireland.2 Evan Ireland
            • Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated: