0
votes

I'm trying to implement data persistance layer with TypeORM for the next logical object model: enter image description here

Diagram source code

The idea is that Provider has collection of AbstractResources which describes common information and holds reference to available Options of this AbstractResources instance.

The exact data types of object stored inside resources collection are inherited from the AbstractResource: Scooter and Bicycle.

I tried both options described at the official Entity Inheritance documentation

  1. The "Concrete Table Inheritance" way (where abstract class with @Entity subclasses are using) is not working because Option entity is targeting to the AbstractResource entity which is not valid entity and doesn't has database table.
  2. The "Single Table Inheritance" way is also not working out of the box becase when I persist Provider with its AbstractResoruce collection as signle request, I see AbstractEntitiy in the type discriminator column. I tried to add property with this name explicitly to the child-classes with the correct values before persistance, but this values overrides during persistance.

    @Entity()
    @TableInheritance({
        column: { name: 'discriminator', type: 'varchar' }
    })
    export abstract class Resource{
    
  3. The "most working" way is "Single Table Inheritance" but with independed collections inside Provider for every child entity type. This way persistance works correctly, reference from AbstractResource to Options is also works correctly, the discriminator column is populated correctly. But the data read receives copy of all entities of all types inside every resource collection (if Provider has 1 Scooter and 1 Bicycle, I'll read 2 Scooters and 2 Bicycles where Biycle collection contains both Bicycle and Scooter). The workaround is to have post-filter after entities read, but it is not 100% right way.

    @OneToMany(type => Bicycle, bicycles => bicycles.provider, {cascade: true, eager: true})
    bicycles: Bicycle[];
    
    
    @OneToMany(type => Scooter, scooters => scooters.provider, {cascade: true, eager: true})
    scooters: Scooter[];
    

What is the correct way to implement this logical data schema with the TypeORM framework?

1

1 Answers

0
votes

The current working solution is to replace all inhiritance with aggregation.

  1. I refactored entities to avoid any inheritance and abstract classes: enter image description here Diagram sources

  2. I introduced business objects layer with the initially required object layaout and hierarchy

  3. Implemented business to/from entities transformation mapper

This is moslty object-design-based solution to make TypeORM work as excpected. Unfortunatelly this solution introduced a lot of extra code and calculations, the supportability is affected. I suppose there could be TypeORM-based solution for the initial problem.