loopbackio / loopbackio/loopback-next

Regression: secondary HasManyThrough inclusion fails with circular dependency

Abierto
#7,599 23 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

bug IoC/Context needs grooming Repository
Lenguaje dominante
TypeScript
Estrellas
5.1k
Forks
1.1k
Merge medio
2 d 21 h
PR fusionados (30 d)
27

Descripción

After the latest release (and possibly the one before - hard to test), a circular dependency error triggers where none did before.

## Steps to reproduce

1. Create 3 models, e.g. User, Participant, Conversation
2. Set up bi-directional HasManyThrough relations (User through Participant to Conversation, Conversation through Participant to User)
3. Use one repository to find instances of the other and include the first, e.g.
`userRepo.conversations(userId).find({include:['users']});`
4. Execute `create`: `userRepo.conversations(userId).create({});`
5. Execute `find` again: `userRepo.conversations(userId).find({include:['users']});`

## Current Behavior

The first execution of `find` succeeds. The second fails with (using Todo <-> Assignment <-> Person from linked branch):
```
Error: Circular dependency detected: repositories.TodoRepository --> @TodoRepository.constructor[2] --> repositories.PersonRepository --> @PersonRepository.constructor[2] --> repositories.TodoRepository
at ResolutionSession.pushBinding (/home/X/project/loopback-next/packages/context/src/resolution-session.ts:228:13)
at Function.runWithBinding (/home/X/project/loopback-next/packages/context/src/resolution-session.ts:107:13)
at Binding.getValue (/home/X/project/loopback-next/packages/context/src/binding.ts:535:40)
at TodoListApplication.getValueOrPromise (/home/X/project/loopback-next/packages/context/src/context.ts:912:32)
at TodoListApplication.get (/home/X/project/loopback-next/packages/context/src/context.ts:712:17)
at getter (/home/X/project/loopback-next/packages/context/src/inject.ts:444:16)
at fetchHasManyThroughModels (/home/X/project/loopback-next/packages/repository/src/relations/has-many/has-many-through.inclusion-resolver.ts:88:30)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at /home/X/project/loopback-next/packages/repository/src/relations/relation.helpers.ts:112:21
at async Promise.all (index 0)
at Object.includeRelatedModels (/home/X/project/loopback-next/packages/repository/src/relations/relation.helpers.ts:120:3)
```

## Expected Behavior

Second execution of `find` on the `HasManyThroughRepositoryFactory` should succeed as well.

## Link to reproduction sandbox

The Todo example at https://github.com/0x0aNL/loopback-next/tree/hmt-circdep-regression is set up with bi-directional HasManyThrough relations: Todo <-> Assignment <-> Person. A test case in `src/__tests__/acceptance/todo.acceptance.ts` executes:
```
await todoRepo.people(1).find({include: ['todos']});
await todoRepo.people(1).create({});
await todoRepo.people(1).find({include: ['todos']});
```

## Additional information

```
> node -e 'console.log(process.platform, process.arch, process.versions.node)'
linux x64 16.1.0
```
```
> npm ls --prod --depth 0 | grep loopback
@loopback/example-todo@3.11.1 /home/X/project/loopback-next/examples/todo
├── @loopback/boot@3.4.1
├── @loopback/core@2.16.1
├── @loopback/repository@3.7.0
├── @loopback/rest-explorer@3.3.1
├── @loopback/rest@9.3.1
├── @loopback/service-proxy@3.2.1
├── loopback-connector-rest@4.0.1
```

It looks as though this regression is introduced between `@loopback/repository@3.5.0 / @loopback/core@2.15.0` and `@loopback/repository@3.6.0 / @loopback/core@2.16.0`.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con packages/repository/src/relations/has-many/has-many-through.inclusion-resolver.ts y la reproducción de Todo en src/__tests__/acceptance/todo.acceptance.ts. Compara los cambios de repository/core entre las versiones 3.5.0/2.15.0 y 3.6.0/2.16.0, y después ejecuta la secuencia de tres pasos find/create/find. Se considera terminado cuando el segundo find incluido tiene éxito sin un error de dependencia circular.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
nodejs, typescript
Área
backend-api-design, databases
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.