-
Type: Bug
-
Status: Closed
-
Priority: Major
-
Resolution: Fixed
-
Affects Version/s: V4.01_OS
-
Fix Version/s: V4.01_ERRATA01
-
Component/s: Protocol
-
Labels:None
-
Environment:
Closed as applied 20203-10-18
-
Proposal:
-
Resolution:
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="CustomerPhoneNumber"> <Key> <PropertyRef Name="Customer/ID" Alias="CustomerID"/> </Key> <Property Name="PhoneNumber" Type="Edm.String" 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="CustomerPhoneNumbers" EntityType="Self.CustomerPhoneNumber"> <NavigationPropertyBinding Path="Customer" Target="Customers"/> </EntitySet> </EntityContainer> </Schema> </edmx:DataServices> </edmx:Edmx>
If a client sends this request:
POST /CustomerPhoneNumber {"Customer":{"ID":123},"PhoneNumber":"+18001234567"}
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 CustomerPhoneNumber (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 CustomerPhoneNumber 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 CustomerPhoneNumber 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.