Closed jdumont0201 closed 5 years ago
@jdumont0201 This is an interesting problem. What is the particular use case you are trying to solve here? I would expect an error when trying to do this because you are essentially defining a recursive relation here ... Todo -> Todo 1. Todo 1 -> Todo 2. Todo 1 -> Todo 3. Todo 2 -> Todo 4. And now the final chain should be as follows:
Todo -> Todo 1 -> Todo 2 -> Todo 4
|-> Todo 3
This can keep going on forever and ever. My suggestion would be to try a different data model where a Model is extended to create new Models.
Define Todo
Model ... Now create 2 new Models as follows:
class ParentTodo extends Todo {
constructor(data?: Partial<Todo>) { super(data); }
}
class ChildTodo extends Todo {
constructor(data?: Partial<Todo>) { super(data); }
}
And now you can establish a relation of ParentTodo hasMany ChildTodo and this shouldn't result in an infinite recursion / stack errors all the while both these Models will rely on the same base model so any changes made to one will reflect to the other.
Thoughts?
There are many models that have fractal properties, i.e. contains entities that have the same properties.
Some usecases: Describe a geographical area that contains smaller area with same properties, itself included in a larger one. Relations are
In Loopback 3, I went with hasManyThough, specifying foreignKey and keyThrough for each pair of relation and two belongsTo relations on the through entity. It allows multiple /contained_in /containing relationships
I also like your inheritence idea, I'll give it a try and keep you informed I will retry on Lookback4 when hasManyThrough is supported. Cheers.
Thanks for providing a use-case! Let me know how the inheritance idea works out / any issues you run into it, we'll be more than happy to help.
As for support for hasManyThrough
, we're working on adding more relations to LoopBack 4 (Ex: this month we'll get belongsTo
). While I don't have a time for hasManyThrough
, having a user ask for it helps us prioritize the relation / feature. Thanks for the feedback! :)
Here is the problem I see purely based on the error stack trace given:
Using the decorators from @loopback/openapi-v3
package will queue up creating JSON definitions for custom models they are decorating. Due to how they're being written, the module will attempt to create definition for Todo
infinitely in the case when it is defined recursively.
Even if we fix this issue, I am not sure whether that would still allow the program to work as intended as @virkt25's comment above. IMO, we need to investigate this issue by:
@loopback/repository-json-schema
@hasMany
decoratorsI'd imagine some language problem we have with JS would be solved by this PR, #1618, via the usage of resolvers, but I'm not too sure.
In my opinion, a recursive hasMany
relation is perfectly valid.
Consider an application modeling company employees. Each manager is an Employee
and supervises one or more other employees (Employee has many Employee). It may be easier to understand when we look at the relation from the other side - an Employee "belongs to" another Employee via manager
relation. In the data schema of Employee
model, each employee has managerId
property acting as a foreign key. (The question is how to deal with the top manager that does not report to any other employee. I am not sure if foreign keys can be optional?)
I like the plan proposed by @shimks in his comment 👍
- creating test cases and fixing the infinite recursion problem for @loopback/repository-json-schema
- creating test cases and investigating recursive use of @hasMany decorators
@jdumont0201 would you like to take a look at this yourself and contribute a patch or two to fix the issues?
I think the following test case is a good starting point - just copy the code into a new test case, modify the model definition to contain a property storing an instance of the same model, and then find out how to make the test pass.
@shimks please correct my advice if needed.
let's do a quick spike:
Discussed with @raymondfeng , this task will be postGA but would like the spike to be in for GA.
@jannyHou , after the spike task is created, could you please mark it as LB4 GA
and put it under the LB4 GA
release? Thanks.
@dhmlau The spike story is created in https://github.com/strongloop/loopback-next/issues/1682
There's a similar issue in BelongsTo. I have a model called Category with a parentId field that points to the parent Category
export class Category extends Entity {
@property({
type: 'number',
id: true,
generated: true
})
id?: number;
@belongsTo(() => Category)
parentId: number;
@belongsTo(() => Domain)
containerId: number;
@property({
type: 'boolean',
default: false,
})
internal?: boolean;
@property({
type: 'string',
required: true,
})
title: string;
@property({
type: 'string',
})
description?: string;
@property({
type: 'string',
})
state?: string;
constructor(data?: Partial<Category>) {
super(data);
}
}
I created a /categories/{id}/parent endpoint per the docs
When I call that endpoint I get this error:
Unhandled error in GET /categories/2/parent: 500 Error: Circular dependency detected: controllers.CategoryParentController --> @CategoryParentController.constructor[0] --> repositories.CategoryRepository --> @CategoryRepository.constructor[2] --> repositories.CategoryRepository
Let me know if that's tied into this issue or if a separate issue should be opened for this one.
@hvlawren could you please post the dependency injection configuration for your CategoryParentController
and CategoryRepository
?
@hvlawren actually, the problem you have encountered is almost certainly different from what is being discussed in this issue, would you mind opening a new GitHub issue please?
I created https://github.com/strongloop/loopback-next/issues/2118 -- Thanks!
@nabdelgadir , could you please add the acceptance criteria based on the spike #1682? Thanks.
Description / Steps to reproduce / Feature proposal
Can we have an hasMany relation between objects of the same Entity ? Say an object that refers to other objects of the same type.
Apparently it cannot find the target key, or loops endlessly when specified explicitly.
Current Behavior
Start from the TodoList example. Add an hasMany relation to Todo that links to other Todos. todo.repository.ts
todo.model.ts
fails with
If I specify the keyTo target in todo.model.ts, then it fails with max call stack exceeded.
Expected Behavior
See Reporting Issues for more tips on writing good issues
Acceptance Criteria