28
votes

I use TypeORM with NestJS and I am not able to save properly an entity.

The connection creation works, postgres is running on 5432 port. Credentials are OK too.

However when I need to save a resource with entity.save() I got :

Connection "default" was not found.


Error
    at new ConnectionNotFoundError (/.../ConnectionNotFoundError.ts:11:22)

I checked the source file of TypeORM ConnectionManager (https://github.com/typeorm/typeorm/blob/master/src/connection/ConnectionManager.ts) but it seems that the first time TypeORM creates connection it attributes "default" name if we don't provide one, which is the case for me.

I setup TypeORM with TypeOrmModule as

TypeOrmModule.forRoot({
      type: config.db.type,
      host: config.db.host,
      port: config.db.port,
      username: config.db.user,
      password: config.db.password,
      database: config.db.database,
      entities: [
        __dirname + '/../../dtos/entities/*.entity.js',
      ]
    })

Of course my constants are correct. Any ideas ?

12
I assume you must provide entities to the TypeORM configuration (e.g. entities: 'src/*/**.entity.ts').VinceOPS
Yes I have referenced my entities this way : entities: [ __dirname + '/../../dtos/entities/*.entity.js', ], I edit my postValentinV

12 Answers

25
votes

You are trying to create a repository or manager without the connection being established.

Try doing this const shopkeeperRepository = getRepository(Shopkeeper); inside a function. it will work

6
votes

the upvoted answer is not necessarily correct, if you not specify the connection name it will default to "default".

const manager = getConnectionManager().get('your_orm_name');
const repository = manager.getRepository<AModel>(Model);
3
votes

We are using lerna and using code from library A in package B.

The problem was that both TypeOrm versions in each package differ.

Solution is to make sure that you have exactly the same version installed in each package.

To be on the safe side, delete your node_modules directory and reinstall everything again with yarn install or npm install

Check your yarn.lock for multiple entries of typeorm and make sure there is only one.

2
votes

If anyone else has this problem in the future, check this out just in case:

I accidentally did "user.save()" instead of "userRepo.save(user)".

(And of course above initializing the connection like this:

const userRepo = getConnection(process.env.NODE_ENV).getRepository(User))

2
votes

I follow the below approach creating the Database class. If the connection doesn't exist then it creates the connection else return the existing connection.

import { Connection, ConnectionManager, ConnectionOptions, createConnection, getConnectionManager } from 'typeorm';

export class Database {
  private connectionManager: ConnectionManager;

  constructor() {
    this.connectionManager = getConnectionManager();
  }

  public async getConnection(name: string): Promise<Connection> {
    const CONNECTION_NAME: string = name;
    let connection: Connection;
    const hasConnection = this.connectionManager.has(CONNECTION_NAME);
    if (hasConnection) {
      connection = this.connectionManager.get(CONNECTION_NAME);
      if (!connection.isConnected) {
        connection = await connection.connect();
      }
    } else {

      const connectionOptions: ConnectionOptions = {
        name: 'default',
        type: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'password',
        database: 'DemoDb',
        synchronize: false,
        logging: true,
        entities: ['src/entities/**/*.js'],
        migrations: ['src/migration/**/*.js'],
        subscribers: ['src/subscriber/**/*.js'],
      };
      connection = await createConnection(connectionOptions);
    }
    return connection;
  }
}


If you are using webpack the make sure entities are imported specifically & returned in array.

    import {User} from 'src/entities/User.ts';
    import {Album} from 'src/entities/Album.ts';
    import {Photos} from 'src/entities/Photos.ts';
    const connectionOptions: ConnectionOptions = {
        name: 'default',
        type: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'password',
        database: 'DemoDb',
        synchronize: false,
        logging: true,
        entities: [User, Album, Photos],
        migrations: ['src/migration/**/*.js'],
        subscribers: ['src/subscriber/**/*.js'],
      };

Finally

  const connectionName = 'default';
  const database = new Database();
  const dbConn: Connection = await database.getConnection(connectionName);
  const MspRepository = dbConn.getRepository(Msp);
  await MspRepository.delete(mspId);
1
votes

For those of you looking for another answer, check this out.

In my case, the issue was because I was passing name in my db config.

export const dbConfig = {
    name: 'myDB',
    ...
}

await createConnection(dbConfig) // like this

As a result, the only connection server knows is myDB not default.

At the same time, in my service, repository was injected without name which will fallback to default. (Service will looking for default connection as a result)

@Service() // typedi
export class Service {
    constructor(
        // inject without name -> fallback to default
        @InjectRepository() private readonly repository
    ) {}
}

As a fix, I removed name property in my db config.

Or you can pass myDB as a parameter for InjectRepository like @InjectRepository('myDB'), either way works.

1
votes

If anyone using Express Router with getRepository(), check the code below

const router = Router();

router.get("/", async function (req: Request, res: Response) {
  // here we will have logic to return all users
  const userRepository = getRepository(User);
  const users = await userRepository.find();
  res.json(users);
});

router.get("/:id", async function (req: Request, res: Response) {
  // here we will have logic to return user by id
  const userRepository = getRepository(User);
  const results = await userRepository.findOne(req.params.id);
  return res.send(results);
});

Just make sure to call getRepository() in every route just like Saras Arya said in the accepted answer.

0
votes

Although Saras Arya has provided the correct answer, I have encountered the same error

ConnectionNotFoundError: Connection "default" was not found.

due to the fact that my typeORM entity did have an @Entity() decorator as well as that it had extended BaseEntity.

The two can't live together.

0
votes

I got this error while using getConnectionOptions for different environments. Using one database for development and another for testing. This is how I fixed it:

const connectionOptions = await getConnectionOptions(process.env.NODE_ENV);
await createConnection({...connectionOptions, name:"default"});

I usegetConnectionOptions to get the connection for the current environment, in order to do that successfully you have to change ormconfig.json to an array, with keys "name" containing the different environments you want, like so:

[
{
    "name" : "development",
    "type": "USER",
    "host": "localhost",
    "port": 5432,
    "username": "postgres",
    "password": "PASS",
    "database": "YOURDB"
},
{
    "name" : "test",
    "type": "USERTEST",
    "host": "localhost",
    "port": 5432,
    "username": "postgres",
    "password": "PASSTEST",
    "database": "YOURDBTEST"
}
]

Now connectionOptions will contain the connection parameters of the current environment, but loading it to createConnection threw the error you pointed. Changing connectionOptions name to "default" fixed the issue.

0
votes

I know it is super weird but someone might need this:

Windows related reason.

I had the same error caused by the current location set with the drive letter in the lower case (d:/apps/app-name/etc).
The problem got fixed once I updated the directory change instruction to use capital D (D:/apps/app-name/etc).

0
votes

After verifying TypeOrm versions is same in both the packages i.e- external package and consumer repository as mentioned by @InsOp still issue persist then issue could be-

Basically when we create an external package - TypeORM tries to get the "default" connection option, but If not found then throws an error:

ConnectionNotFoundError: Connection "default" was not found.

We can solve this issue by doing some kind of sanity check before establishing a connection - luckily we have .has() method on getConnectionManager().

import { Connection, getConnectionManager, getConnectionOptions, 
  createConnection, getConnection, QueryRunner } from 'typeorm';
    
    async init() {
    let connection: Connection;
    let queryRunner: QueryRunner;

     if (!getConnectionManager().has('default')) {
        const connectionOptions = await getConnectionOptions();
        connection = await createConnection(connectionOptions);
      } else {
        connection = getConnection();
      }

    queryRunner = connection.createQueryRunner(); 
 }

Above is a quick code-snippet which was the actual root cause for this issue but If you are interested to see complete working repositories (different examples) -

  • External NPM Package :
  • Consumer of above package : nest-typeorm-postgre (specific files- package.json, src/countries/countries.service.ts & countries.module.ts)
0
votes

In my case was that I have an array of multiple connections, instead of just one. You have 2 alternatives.

  • To have at least one default named connection, example:
createConnections([
  {
    name: 'default',
    type: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'users',
    entities: [`${__dirname}/entity/*{.js,.ts}`],
    synchronize: true,
    logging: true
  }
]);
  • To be specific when using the connection:
import {getConnection} from "typeorm";

const db1Connection = getConnection("db1Connection");
// you can work with "db1" database now...