Обработка значений null и undefined в условиях WHERE
Эта страница переведена PageTurner AI (бета). Не одобрена официально проектом. Нашли ошибку? Сообщить о проблеме →
В условиях 'WHERE' значения null и undefined не являются строго допустимыми в TypeORM.
TypeScript запрещает передачу явного значения null при компиляции (если в tsconfig.json включена опция strictNullChecks). Поведение по умолчанию при выполнении — выброс ошибки при обнаружении null или undefined в условиях.
Обработку значений null и undefined можно настроить через опцию invalidWhereValuesBehavior в конфигурации источника данных. Это применяется к высокоуровневым операциям: методам поиска, репозитория и EntityManager (update, delete, softDelete, restore).
Эта настройка не влияет на методы QueryBuilder .where(), .andWhere() и .orWhere(). QueryBuilder — низкоуровневый API, где null/undefined передаются "как есть". Для явной обработки null используйте оператор IsNull() или параметризованные условия.
Поведение по умолчанию
По умолчанию TypeORM выбрасывает ошибку при обнаружении null или undefined в условиях WHERE. Это предотвращает неожиданные результаты и помогает выявлять ошибки:
// Both queries will throw an error
const posts1 = await repository.find({
where: {
text: null,
},
})
// Error: Null value encountered in property 'text' of a where condition.
const posts2 = await repository.find({
where: {
text: undefined,
},
})
// Error: Undefined value encountered in property 'text' of a where condition.
Для поиска значений null используйте оператор IsNull (подробнее в Опциях поиска):
const posts = await repository.find({
where: {
text: IsNull(),
},
})
Настройка
Поведение при обработке значений null и undefined можно настроить с помощью опции invalidWhereValuesBehavior в конфигурации источника данных:
const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
null: "ignore" | "sql-null" | "throw",
undefined: "ignore" | "throw",
},
})
Опции поведения для null
Поведение null может принимать одно из трёх значений:
'ignore'
Значения JavaScript null в условиях WHERE игнорируются, и свойство про пускается:
const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
null: "ignore",
},
})
// This will return all posts, ignoring the text property
const posts = await repository.find({
where: {
text: null,
},
})
'sql-null'
Значения JavaScript null преобразуются в условия SQL NULL:
const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
null: "sql-null",
},
})
// This will only return posts where the text column is NULL in the database
const posts = await repository.find({
where: {
text: null,
},
})
'throw' (по умолчанию)
Значения JavaScript null вызывают исключение TypeORMError:
const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
null: "throw",
},
})
// This will throw an error
const posts = await repository.find({
where: {
text: null,
},
})
// Error: Null value encountered in property 'text' of a where condition.
// To match with SQL NULL, the IsNull() operator must be used.
// Set 'invalidWhereValuesBehavior.null' to 'ignore' or 'sql-null' in data source options to skip or handle null values.
Опции поведения для undefined
Поведение undefined может принимать одно из двух значений:
'ignore'
Значения JavaScript undefined в условиях WHERE игнорируются, и свойство пропускается:
const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
undefined: "ignore",
},
})
// This will return all posts, ignoring the text property
const posts = await repository.find({
where: {
text: undefined,
},
})
'throw' (по умолчанию)
Значения JavaScript undefined вызывают исключение TypeORMError:
const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
undefined: "throw",
},
})
// This will throw an error
const posts = await repository.find({
where: {
text: undefined,
},
})
// Error: Undefined value encountered in property 'text' of a where condition.
// Set 'invalidWhereValuesBehavior.undefined' to 'ignore' in data source options to skip properties with undefined values.
Это относится только к явно установленным значениям undefined, а не к отсутствующим свойствам.
Совместное использование опций
Оба поведения можно настроить независимо для полного контроля:
const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
null: "sql-null",
undefined: "throw",
},
})
Такая конфигурация:
-
Преобразует JavaScript
nullв SQLNULLв условиях WHERE -
Выбросит исключение при обнаружении значений
undefined -
Будет игнорировать свойства, отсутствующие в условии WHERE
Этот подход полезен, когда требуется:
-
Явно указывать поиск значений NULL в базе данных
-
Отлавливать потенциальные ошибки программирования, при которых значения undefined могут попасть в запросы
Поддерживаемые операции
Настройка invalidWhereValuesBehavior применяется только к высокоуровневым операциям TypeORM, но не к прямому методу .where() в QueryBuilder:
Операции поиска
// Repository.find() / findOne() / findBy() / findOneBy()
await repository.find({ where: { text: null } }) // Respects invalidWhereValuesBehavior
// EntityManager.find() / findOne() / findBy() / findOneBy()
await manager.find(Post, { where: { text: null } }) // Respects invalidWhereValuesBehavior
Методы репозитория и EntityManager
// Repository.update()
await repository.update({ text: null }, { title: "Updated" }) // Respects invalidWhereValuesBehavior
// Repository.delete()
await repository.delete({ text: null }) // Respects invalidWhereValuesBehavior
// EntityManager.update()
await manager.update(Post, { text: null }, { title: "Updated" }) // Respects invalidWhereValuesBehavior
// EntityManager.delete()
await manager.delete(Post, { text: null }) // Respects invalidWhereValuesBehavior
// EntityManager.softDelete()
await manager.softDelete(Post, { text: null }) // Respects invalidWhereValuesBehavior
QueryBuilder с setFindOptions
// setFindOptions goes through the find-options path, so it respects the setting
await dataSource
.createQueryBuilder(Post, "post")
.setFindOptions({ where: { text: null } }) // Respects invalidWhereValuesBehavior
.getMany()
Не затрагивается: QueryBuilder .where()
Методы .where(), .andWhere() и .orWhere() в QueryBuilder — низкоуровневые API и не зависят от этой настройки. Значения null и undefined передаются без изменений:
// This does NOT respect invalidWhereValuesBehavior — null passes through as-is
await dataSource
.createQueryBuilder()
.update(Post)
.set({ title: "Updated" })
.where({ text: null })
.execute()
Поведение null и undefined в QueryBuilder .where()
Поскольку QueryBuilder — низкоуровневый API, значения null и undefined не проверяются и не преобразуются. Понимание их поведения критично для избежания неожиданных результатов.
null в QueryBuilder .where()
При передаче null в объектном стиле .where() генерируется SQL-проверка на равенство NULL:
await dataSource
.createQueryBuilder(Post, "post")
.where({ text: null })
.getMany()
// Generates: WHERE post.text = NULL
В SQL column = NULL всегда ложно — ничто не равно NULL. Это т запрос вернёт ноль результатов, что почти наверняка не ожидается. Для поиска NULL используйте оператор IsNull():
import { IsNull } from "typeorm"
await dataSource
.createQueryBuilder(Post, "post")
.where({ text: IsNull() })
.getMany()
// Generates: WHERE post.text IS NULL
Или строковое условие:
await dataSource
.createQueryBuilder(Post, "post")
.where("post.text IS NULL")
.getMany()
undefined в QueryBuilder .where()
При передаче undefined поведение идентично — генерируется WHERE column = NULL, что всегда ложно:
await dataSource
.createQueryBuilder(Post, "post")
.where({ text: undefined })
.getMany()
// Generates: WHERE post.text = NULL
// Returns: zero results
Сводная таблица
| Value | High-level API (find/repository/manager) | QueryBuilder .where() |
|---|---|---|
null with "ignore" | Property skipped — no filter | WHERE col = NULL — zero results |
null with "sql-null" | WHERE col IS NULL | WHERE col = NULL — zero results |
null with "throw" (default) | Throws error | WHERE col = NULL — zero results |
undefined with "ignore" | Property skipped — no filter | WHERE col = NULL — zero results |
undefined with "throw" (default) | Throws error | WHERE col = NULL — zero results |
IsNull() | WHERE col IS NULL | WHERE col IS NULL |
Всегда используйте IsNull() для поиска SQL NULL, независимо от API. Он корректно работает в высокоуровневых операциях и QueryBuilder.