InjectModel decorator for multiple databases is broken since version 9.1.0
Closed this issue · 1 comments
Did you read the migration guide?
- I have read the whole migration guide
Is there an existing issue that is already proposing this?
- I have searched the existing issues
Potential Commit/PR that introduced the regression
Versions
9.1.0
Describe the regression
Since version 9.1.0, the InjectModel decorator for multiple databases is malfunctioning, resulting in an error in resolving dependencies. The only functional approach is to use the connectionName parameter as follows: @InjectModel(modelName, connectionName). It's imperative that this parameter remains optional.
Root cause analysis: The function getModelToken was changed (referenced in PR #1023), with the connectionName becoming a part of the provider name in the form of ${getConnectionToken(connectionName)}/${model}Model
.
One potential solution involves introducing two provider tokens for each model, one with a connectionName and the other without.
Minimum reproduction code
@Module({
imports: [
MongooseModule.forFeature(
[
{ name: SomeModel1.name, schema: Schema1, },
],
mongoConnection1,
),
MongooseModule.forFeature(
[
{ name: SomeModel2.name, schema: Schema2, },
],
mongoConnection2,
),
],
})
export class AppModule {}
// Not working: Nest can't resolve dependencies of the SomeService (?)
@Injectable()
export class SomeService {
constructor(@InjectModel(SomeModel1.name) private readonly model: Model<SomeDocument>) {}
}
// Working
@Injectable()
export class SomeService {
constructor(@InjectModel(SomeModel1.name, mongoConnection1) private readonly model: Model<SomeDocument>) {}
}
Expected behavior
connectionName parameter of InjectModel decorator should be optional
@Injectable()
export class SomeService {
constructor(@InjectModel(SomeModel1.name) private readonly model: Model<SomeDocument>) {}
}
Other
No response
In my opinion, it shouldn't remain optional if you have multiple databases. If you have Connection1
and Connection2
and you are @InjectModel(SomeModel1.name)
and SomeModel1
is in both connections, are you injecting it for Connection1
or Connection2
? By adding the connection name, you are making the explicit, conscious choice on which connection you are using, and leading to less guesswork by other devs, and by the framework. If you want to not need to pass a connection name by default, and use one of the X connections, leave the default connection without a name, and the framework will properly use the connection name default
. This is how it has been working in both @nestjs/sequelize
and @nestjs/typeorm
and has pretty much been accepted as the right way to go about multiple connections