Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
None
-
Patch, Important
Description
When multiple links (associations) exist between the same two entity sets, the annotation processor does not distinguish between them, even if you name the associations explicitly. The EDM provider binds the same association (whatever it finds first) to all navigation properties between this pair of entity sets, reading and writing relations/links produces the same data for each navigation property, even if they should use different associations.
Steps to reproduce:
- Checkout cars-annotation-archetype
- Add property "previousDrivers" to entity type Car (see Car.java)
- Add property "previousCars" to entity type Driver (see Driver.java)
- Optional: explicitly name association for properties "Car.Driver" and "Driver.Car"
- Run example service
- Retrieve EDMX metadata
Expected results:
Properties "previousDrivers" and "previousCars" use association "Car_previousDrivers_2_Driver_previousCars":
<EntityType Name="Car">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.String" Nullable="true"/>
<Property Name="Model" Type="Edm.String" Nullable="true"/>
<Property Name="Price" Type="Edm.Double" Nullable="true"/>
<Property Name="ModelYear" Type="Edm.Int32" Nullable="true"/>
<Property Name="Updated" Type="Edm.DateTime" Nullable="true"/>
<NavigationProperty Name="Manufacturer" Relationship="MyFormula.r_Cars_2_r_Manufacturer" FromRole="r_Cars" ToRole="r_Manufacturer"/>
<NavigationProperty Name="Driver" Relationship="MyFormula.Car_currentDriver_2_Driver_currentCar" FromRole="r_Car" ToRole="r_Driver"/>
<NavigationProperty Name="PreviousDrivers" Relationship="MyFormula.Car_previousDrivers_2_Driver_previousCars" FromRole="r_PreviousCars" ToRole="r_PreviousDrivers"/>
</EntityType>
<EntityType Name="Driver">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int64" Nullable="true"/>
<Property Name="Name" Type="Edm.String" Nullable="true"/>
<Property Name="Lastname" Type="Edm.String" Nullable="true"/>
<Property Name="Nickname" Type="Edm.String" Nullable="true"/>
<Property Name="Birthday" Type="Edm.DateTime" Nullable="true"/>
<NavigationProperty Name="Car" Relationship="MyFormula.Car_currentDriver_2_Driver_currentCar" FromRole="r_Driver" ToRole="r_Car"/>
<NavigationProperty Name="PreviousCars" Relationship="MyFormula.Car_previousDrivers_2_Driver_previousCars" FromRole="r_PreviousDrivers" ToRole="r_PreviousCars"/>
</EntityType>
Actual results:
Properties "previousDrivers" and "previousCars" use association "Car_currentDriver_2_Driver_currentCar":
<EntityType Name="Car">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.String" Nullable="true"/>
<Property Name="Model" Type="Edm.String" Nullable="true"/>
<Property Name="Price" Type="Edm.Double" Nullable="true"/>
<Property Name="ModelYear" Type="Edm.Int32" Nullable="true"/>
<Property Name="Updated" Type="Edm.DateTime" Nullable="true"/>
<NavigationProperty Name="Manufacturer" Relationship="MyFormula.r_Cars_2_r_Manufacturer" FromRole="r_Cars" ToRole="r_Manufacturer"/>
<NavigationProperty Name="Driver" Relationship="MyFormula.Car_currentDriver_2_Driver_currentCar" FromRole="r_Car" ToRole="r_Driver"/>
<NavigationProperty Name="PreviousDrivers" Relationship="MyFormula.Car_currentDriver_2_Driver_currentCar" FromRole="r_Car" ToRole="r_Driver"/>
</EntityType>
<EntityType Name="Driver">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int64" Nullable="true"/>
<Property Name="Name" Type="Edm.String" Nullable="true"/>
<Property Name="Lastname" Type="Edm.String" Nullable="true"/>
<Property Name="Nickname" Type="Edm.String" Nullable="true"/>
<Property Name="Birthday" Type="Edm.DateTime" Nullable="true"/>
<NavigationProperty Name="Car" Relationship="MyFormula.Car_currentDriver_2_Driver_currentCar" FromRole="r_Driver" ToRole="r_Car"/>
<NavigationProperty Name="PreviousCars" Relationship="MyFormula.Car_currentDriver_2_Driver_currentCar" FromRole="r_Driver" ToRole="r_Car"/>
</EntityType>
Workaround:
- Only workaround is to change your model. You could promote the associations to entity types only consisting of navigation properties, for instance.
Additional information:
- Interface Datasource lacks a means of communicating the link followed when reading or writing related data. Only the target entity set can be communicated. The fix must change this.
- The patch currently just adds an optional parameter to the relevant interface methods passing the navigation property. When the parameter is not passed, the navigation property is guessed as before. This breaks applications that directly use the interface, but only those.
- Obviously, there is no point in both changing the interface and keeping the old guessing behavior. But which of both is the correct choice?
-
- (Incompatible change) Change the relevant interface methods and pass the necessary navigation property.
- (Compatible change) Make an extension interface with new methods that additionally pass the navigation property and detect whether the extension interface is supported by the Datasource implementation.
- Other: ___________________________