Description
Is there an existing issue that is already proposing this?
- I have searched the existing issues
Is your feature request related to a problem? Please describe it
createTypeOrmProviders currently injects getConnection and resolves the repositories directly from the connection. However, there are certain scenarios when you'd want to resolve the repository from the EntityManager, such as when running in a transaction.
Describe the solution you'd like
I'm proposing changing the createTypeOrmProviders function to inject the EntityManager and use that to initialize the repositories.
export function createTypeOrmProviders(
entities?: EntityClassOrSchema[],
dataSource?: DataSource | DataSourceOptions | string,
): Provider[] {
return (entities || []).map((entity) => ({
provide: getRepositoryToken(entity, dataSource),
useFactory: (entityManager: EntityManager) => {
const enitityMetadata = dataSource.entityMetadatas.find((meta) => meta.target === entity)
const isTreeEntity = typeof enitityMetadata?.treeType !== 'undefined'
return isTreeEntity
? entityManager.getTreeRepository(entity)
: entityManager.connection.options.type === 'mongodb'
? entityManager.getMongoRepository(entity)
: entityManager.getRepository(entity);
},
inject: [getEntityManagerToken(dataSource)],
/**
* Extra property to workaround dynamic modules serialisation issue
* that occurs when "TypeOrm#forFeature()" method is called with the same number
* of arguments and all entities share the same class names.
*/
targetEntitySchema: getMetadataArgsStorage().tables.find(
(item) => item.target === entity,
),
}));
}
Teachability, documentation, adoption, migration strategy
This should theoretically be a non-breaking change to all users of the library. We're merely changing which object we're calling getRepository on. In fact, DataSource's getRepository method just proxies to the manager anyway.
What is the motivation / use case for changing the behavior?
The instance of manager changes when you open a transaction. That manager instance has to be used to generate the repository, otherwise the transaction is ignored.
Currently, the only method for working around this is overriding each Repository provider. This would allow someone to override the EntityManager and then all repositories created will use that manager instance.