Aliheym / typeorm-transactional

A Transactional Method Decorator for TypeORM that uses Async Local Storage or cls-hooked to handle and propagate transactions between different repositories and service methods.
MIT License
201 stars 27 forks source link

Error when running E2E tests with Nest.js #10

Open no-creative-name opened 1 year ago

no-creative-name commented 1 year ago

Hi there,

thanks for the package! It really is super useful. My issue is that we can't run our E2E tests with it as of now. We get the console error Error: DataSource with name "default" has already added. all the time. I assume it has to do with the dataSourceFactory being called multiple times (in multiple TestingModules) for the same database. Any suggestion how to approach/debug this? The setup is more or less the same as the default testing setup that Nest.js suggests.

Screenshot 2022-09-28 at 16 32 31

Aliheym commented 1 year ago

Hi, thanks for your issue. I think I need to investigate this more to handle this.

Now you can also use something like that to prevent adding the data source several times:

import { addTransactionalDataSource, getDataSourceByName } from 'typeorm-transactional';

// ...

TypeOrmModule.forRootAsync({
    dataSourceFactory: async (options) => {
      return getDataSourceByName('default') || addTransactionalDataSource(new DataSource(options));
    },
  });

or

import { addTransactionalDataSource, deleteDataSourceByName } from 'typeorm-transactional';

// ...

TypeOrmModule.forRootAsync({
    dataSourceFactory: async (options) => {
      deleteDataSourceByName('default');

      return addTransactionalDataSource(new DataSource(options));
    },
  });
no-creative-name commented 1 year ago

If I use the getDataSourceByName workaround, then I get the error Error: No CLS namespace defined in your app ... please call initializeTransactionalContext() before application start. when running the tests. Even though I actually call initializeTransactionalContext() in the beginning of my bootstrap() function. It seems like something's off at a deeper level here.

Edit: My bad, I forgot that bootstrap() wasn't called by the E2E test setup. When I call initializeTransactionalContext() in my E2E setup function it works. Thanks a bunch! If you need testing or anything else for the main issue to solve here, let me know.

Aliheym commented 1 year ago

Thanks! Will notify you.

dsmabulage commented 7 months ago
      return getDataSourceByName('default') || addTransactionalDataSource(new DataSource(options));

Thank you. If I'm not mistaken if we add a name to options, if we use multiple data sources, all the data sources get the name as the default