davidmoten / odata-client

Java client generator for a service described by OData CSDL 4.0 metadata. Includes Microsoft Graph clients (v1.0 and Beta), Graph Explorer client, Analytics for DevOps, Dynamics CRM clients
Apache License 2.0
36 stars 8 forks source link

Support entities without keys #74

Closed davidmoten closed 3 years ago

davidmoten commented 4 years ago

At the moment odata-client ignores with a warning or fails (configurable) if it encounters an Entity without a Key (inherited or otherwise). In fact this is sometimes legal as per spec:

An entity is uniquely identified within an entity set by its key. A key MAY be specified if the entity type does not specify a base type that already has a key declared.

In order to be specified as the type of an entity set or a collection-valued containment navigation property, the entity type MUST either specify a key or inherit its key from its base type.

In OData 4.01 responses entity types used for singletons or single-valued navigation properties do not require a key. In OData 4.0 responses entity types used for singletons or single-valued navigation properties MUST have a key defined.

An example of this is from Dynamics CRM v9.1 metadata:

<EntityType Name="expando" BaseType="mscrm.crmbaseentity" OpenType="true"/>

Neither expando nor crmbaseentity have a key but this is probably legal as there is no reference to expando anywhere else in the document (of course this prompts a question as to its usefulness).

This appears to be very unusual in OData services so this can be considered a low priority task.

davidmoten commented 3 years ago

An example from Graph beta metadata that should be supported but is not currently:

<Singleton Name="auditLogs" Type="microsoft.graph.auditLogRoot"/>
<EntityType Name="auditLogRoot">
    <NavigationProperty Name="directoryAudits" Type="Collection(graph.directoryAudit)" ContainsTarget="true"/>
    <NavigationProperty Name="directoryProvisioning" Type="Collection(graph.provisioningObjectSummary)" ContainsTarget="true"/>
    <NavigationProperty Name="provisioning" Type="Collection(graph.provisioningObjectSummary)" ContainsTarget="true"/>
    <NavigationProperty Name="restrictedSignIns" Type="Collection(graph.restrictedSignIn)" ContainsTarget="true"/>
    <NavigationProperty Name="signIns" Type="Collection(graph.signIn)" ContainsTarget="true"/>
</EntityType>
davidmoten commented 3 years ago

A short look at the use suggests that entities without keys are only being used by Singletons. Might be useful to simplify the problem but we'll see.

davidmoten commented 3 years ago

Fixed in PR #134, released now in 0.1.53