Carsten Milkau created OLINGO-1387:
--------------------------------------

             Summary: olingo-odata2-annotation-processor: support multiple 
links between the same entity sets
                 Key: OLINGO-1387
                 URL: https://issues.apache.org/jira/browse/OLINGO-1387
             Project: Olingo
          Issue Type: Improvement
          Components: odata2-annotation
            Reporter: Carsten Milkau
             Fix For: V2 2.0.12, V2 2.1.0
         Attachments: Car.java, Driver.java, 
odata2-annotation-processor-multiple-links-rc1.patch

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":

 
{color:#0000ff}<{color}{color:#800000}EntityType{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Car">{color}
{color:#0000ff}<{color}{color:#800000}Key{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}PropertyRef{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Id"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}</{color}{color:#800000}Key{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Id"{color} 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.String"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Model"{color} 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.String"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Price"{color} 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.Double"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"ModelYear"{color}
 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.Int32"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Updated"{color}
 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.DateTime"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}NavigationProperty{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Manufacturer"{color}
 
{color:#ff0000}Relationship{color}{color:#000000}={color}{color:#0000ff}"MyFormula.r_Cars_2_r_Manufacturer"{color}
 
{color:#ff0000}FromRole{color}{color:#000000}={color}{color:#0000ff}"r_Cars"{color}
 
{color:#ff0000}ToRole{color}{color:#000000}={color}{color:#0000ff}"r_Manufacturer"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}NavigationProperty{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Driver"{color} 
{color:#ff0000}Relationship{color}{color:#000000}={color}{color:#0000ff}"MyFormula.Car_currentDriver_2_Driver_currentCar"{color}
 
{color:#ff0000}FromRole{color}{color:#000000}={color}{color:#0000ff}"r_Car"{color}
 
{color:#ff0000}ToRole{color}{color:#000000}={color}{color:#0000ff}"r_Driver"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}NavigationProperty{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"PreviousDrivers"{color}
 
{color:#ff0000}Relationship{color}{color:#000000}={color}{color:#0000ff}"MyFormula.Car_previousDrivers_2_Driver_previousCars"{color}
 
{color:#ff0000}FromRole{color}{color:#000000}={color}{color:#0000ff}"r_PreviousCars"{color}
 
{color:#ff0000}ToRole{color}{color:#000000}={color}{color:#0000ff}"r_PreviousDrivers"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}</{color}{color:#800000}EntityType{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}EntityType{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Driver">{color}
{color:#0000ff}<{color}{color:#800000}Key{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}PropertyRef{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Id"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}</{color}{color:#800000}Key{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Id"{color} 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.Int64"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Name"{color} 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.String"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Lastname"{color}
 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.String"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Nickname"{color}
 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.String"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Birthday"{color}
 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.DateTime"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}NavigationProperty{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Car"{color} 
{color:#ff0000}Relationship{color}{color:#000000}={color}{color:#0000ff}"MyFormula.Car_currentDriver_2_Driver_currentCar"{color}
 
{color:#ff0000}FromRole{color}{color:#000000}={color}{color:#0000ff}"r_Driver"{color}
 
{color:#ff0000}ToRole{color}{color:#000000}={color}{color:#0000ff}"r_Car"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}NavigationProperty{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"PreviousCars"{color}
 
{color:#ff0000}Relationship{color}{color:#000000}={color}{color:#0000ff}"MyFormula.Car_previousDrivers_2_Driver_previousCars"{color}
 
{color:#ff0000}FromRole{color}{color:#000000}={color}{color:#0000ff}"r_PreviousDrivers"{color}
 
{color:#ff0000}ToRole{color}{color:#000000}={color}{color:#0000ff}"r_PreviousCars"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}</{color}{color:#800000}EntityType{color}{color:#0000ff}>{color}
*Actual results:*

Properties "previousDrivers" and "previousCars" use association 
"Car_currentDriver_2_Driver_currentCar":

 
{color:#0000ff}<{color}{color:#800000}EntityType{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Car">{color}
{color:#0000ff}<{color}{color:#800000}Key{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}PropertyRef{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Id"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}</{color}{color:#800000}Key{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Id"{color} 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.String"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Model"{color} 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.String"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Price"{color} 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.Double"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"ModelYear"{color}
 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.Int32"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Updated"{color}
 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.DateTime"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}NavigationProperty{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Manufacturer"{color}
 
{color:#ff0000}Relationship{color}{color:#000000}={color}{color:#0000ff}"MyFormula.r_Cars_2_r_Manufacturer"{color}
 
{color:#ff0000}FromRole{color}{color:#000000}={color}{color:#0000ff}"r_Cars"{color}
 
{color:#ff0000}ToRole{color}{color:#000000}={color}{color:#0000ff}"r_Manufacturer"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}NavigationProperty{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Driver"{color} 
{color:#ff0000}Relationship{color}{color:#000000}={color}{color:#0000ff}"MyFormula.Car_currentDriver_2_Driver_currentCar"{color}
 
{color:#ff0000}FromRole{color}{color:#000000}={color}{color:#0000ff}"r_Car"{color}
 
{color:#ff0000}ToRole{color}{color:#000000}={color}{color:#0000ff}"r_Driver"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}NavigationProperty{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"PreviousDrivers"{color}
 
{color:#ff0000}Relationship{color}{color:#000000}={color}{color:#0000ff}"MyFormula.Car_currentDriver_2_Driver_currentCar"{color}
 
{color:#ff0000}FromRole{color}{color:#000000}={color}{color:#0000ff}"r_Car"{color}
 
{color:#ff0000}ToRole{color}{color:#000000}={color}{color:#0000ff}"r_Driver"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}</{color}{color:#800000}EntityType{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}EntityType{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Driver">{color}
{color:#0000ff}<{color}{color:#800000}Key{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}PropertyRef{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Id"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}</{color}{color:#800000}Key{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Id"{color} 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.Int64"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Name"{color} 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.String"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Lastname"{color}
 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.String"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Nickname"{color}
 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.String"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}Property{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Birthday"{color}
 
{color:#ff0000}Type{color}{color:#000000}={color}{color:#0000ff}"Edm.DateTime"{color}
 
{color:#ff0000}Nullable{color}{color:#000000}={color}{color:#0000ff}"true"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}NavigationProperty{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"Car"{color} 
{color:#ff0000}Relationship{color}{color:#000000}={color}{color:#0000ff}"MyFormula.Car_currentDriver_2_Driver_currentCar"{color}
 
{color:#ff0000}FromRole{color}{color:#000000}={color}{color:#0000ff}"r_Driver"{color}
 
{color:#ff0000}ToRole{color}{color:#000000}={color}{color:#0000ff}"r_Car"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}<{color}{color:#800000}NavigationProperty{color} 
{color:#ff0000}Name{color}{color:#000000}={color}{color:#0000ff}"PreviousCars"{color}
 
{color:#ff0000}Relationship{color}{color:#000000}={color}{color:#0000ff}"MyFormula.Car_currentDriver_2_Driver_currentCar"{color}
 
{color:#ff0000}FromRole{color}{color:#000000}={color}{color:#0000ff}"r_Driver"{color}
 
{color:#ff0000}ToRole{color}{color:#000000}={color}{color:#0000ff}"r_Car"{color}{color:#800000}/{color}{color:#0000ff}>{color}
{color:#0000ff}</{color}{color:#800000}EntityType{color}{color:#0000ff}>{color}
 *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: ___________________________

 



--
This message was sent by Atlassian Jira
(v8.3.2#803003)

Reply via email to