← назад к разделу

DataSource владеет конфигурацией и пулом соединений. EntityManager выполняет операции с сущностями. Их разделяют, чтобы настройки жили в одном месте, а сценарии не создавали собственные пулы.

Инициализация один раз

import { DataSource } from 'typeorm';
import { Product } from './product.entity';

export const dataSource = new DataSource({
  type: 'postgres',
  url: process.env.DATABASE_URL,
  entities: [Product],
  migrations: [],
  synchronize: false,
});

await dataSource.initialize();

initialize открывает пул и проверяет соединение. Повторный вызов в каждом запросе - ошибка жизненного цикла. В NestJS инициализацией и закрытием управляет TypeOrmModule.forRoot, поэтому второй ручной DataSource не нужен.

DataSource используют для транзакций и специальных операций, dataSource.manager - для обычных вызовов EntityManager. Репозиторий конкретной сущности получают через getRepository(Product).

EntityManager и репозиторий

const product = dataSource.manager.create(Product, {
  name: 'Кофемолка',
  price: 4990,
});
await dataSource.manager.save(product);

create создает объект в памяти, save записывает его. Для чтения используют find, findOne или QueryBuilder, а не повторное создание соединения.

Пул ограничен. Запросы, которые не завершены, удерживают соединение и мешают остальным. Транзакции заканчивают коммитом или откатом, процесс при остановке закрывает DataSource через lifecycle NestJS.

Коротко

  • DataSource инициализируют один раз и закрывают при остановке.
  • EntityManager выполняет операции, репозиторий ограничивает их одной сущностью.
  • create не записывает объект, save записывает.
  • Пул нельзя создавать на запрос или оставлять транзакции открытыми.
  • В NestJS жизненным циклом управляет TypeOrmModule.

Что почитать дальше