Zum Hauptinhalt springen

Umgang mit null- und undefined-Werten in WHERE-Bedingungen

Inoffizielle Beta-Übersetzung

Diese Seite wurde von PageTurner AI übersetzt (Beta). Nicht offiziell vom Projekt unterstützt. Fehler gefunden? Problem melden →

In 'WHERE'-Bedingungen sind die Werte null und undefined in TypeORM nicht als strikt gültige Werte definiert.

Das Übergeben eines bekannten null-Werts wird von TypeScript zur Kompilierzeit verhindert (wenn du strictNullChecks in tsconfig.json aktiviert hast). Standardmäßig lösen zur Laufzeit auftretende null- und undefined-Werte einen Fehler aus.

Das Verhalten für null- und undefined-Werte kannst du über die Konfigurationsoption invalidWhereValuesBehavior in deinen Data-Source-Optionen anpassen. Dies gilt für High-Level-Operationen wie Find-Operationen, Repository-Methoden und EntityManager-Methoden (update, delete, softDelete, restore).

Warnung

Diese Einstellung wirkt sich nicht auf die .where(), .andWhere() oder .orWhere()-Methoden des QueryBuilders aus. QueryBuilder ist eine Low-Level-API, bei der null/undefined-Werte unverändert durchgereicht werden. Verwende für explizite Null-Behandlung den IsNull()-Operator oder parametrisierte Bedingungen im QueryBuilder.

Standardverhalten

Standardmäßig wirft TypeORM einen Fehler, wenn null oder undefined in WHERE-Bedingungen auftreten. Dies verhindert unerwartete Ergebnisse und hilft, potenzielle Fehler frühzeitig zu erkennen:

// 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.

Um Null-Werte in WHERE-Bedingungen abzugleichen, verwende den IsNull-Operator (Details siehe Find Options):

const posts = await repository.find({
where: {
text: IsNull(),
},
})

Konfiguration

Du kannst mit der Option invalidWhereValuesBehavior in deiner Data-Source-Konfiguration anpassen, wie mit null- und undefined-Werten umgegangen wird:

const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
null: "ignore" | "sql-null" | "throw",
undefined: "ignore" | "throw",
},
})

Optionen für Null-Verhalten

Das null-Verhalten kann auf einen von drei Werten gesetzt werden:

'ignore'

JavaScript-null-Werte in WHERE-Bedingungen werden ignoriert und die Eigenschaft übersprungen:

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-Werte werden in SQL-NULL-Bedingungen umgewandelt:

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' (Standard)

JavaScript-null-Werte lösen einen TypeORMError aus:

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.

Optionen für Undefined-Verhalten

Das undefined-Verhalten kann auf einen von zwei Werten gesetzt werden:

'ignore'

JavaScript-undefined-Werte in WHERE-Bedingungen werden ignoriert und die Eigenschaft übersprungen:

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' (Standard)

JavaScript-undefined-Werte lösen einen TypeORMError aus:

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.

Hinweis: Dies gilt nur für explizit gesetzte undefined-Werte, nicht für weggelassene Eigenschaften.

Kombinierte Verwendung beider Optionen

Beide Verhaltensweisen können unabhängig konfiguriert werden, um maximale Kontrolle zu erreichen:

const dataSource = new DataSource({
// ... other options
invalidWhereValuesBehavior: {
null: "sql-null",
undefined: "throw",
},
})

Diese Konfiguration bewirkt:

  1. Umwandlung von JavaScript-null in SQL-NULL in WHERE-Bedingungen

  2. Auslösen eines Fehlers bei Auftreten von undefined-Werten

  3. Weiterhin Ignorieren nicht angegebener Eigenschaften in der WHERE-Klausel

Diese Kombination ist nützlich, wenn Sie:

  • Explizit nach NULL-Werten in der Datenbank suchen

  • Potenzielle Programmierfehler abfangen, bei denen undefined-Werte in Ihre Abfragen gelangen könnten

Unterstützte Operationen

Die invalidWhereValuesBehavior-Konfiguration gilt für High-Level-TypeORM-Operationen, nicht für die direkte .where()-Methode des QueryBuilders:

Find-Operationen

// 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

Repository- und EntityManager-Methoden

// 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 mit 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()

Nicht betroffen: QueryBuilder .where()

Die .where(), .andWhere() und .orWhere()-Methoden des QueryBuilders sind Low-Level-APIs und werden nicht von dieser Einstellung beeinflusst. Null- und undefined-Werte werden unverändert durchgereicht:

// This does NOT respect invalidWhereValuesBehavior — null passes through as-is
await dataSource
.createQueryBuilder()
.update(Post)
.set({ title: "Updated" })
.where({ text: null })
.execute()

Verhalten von null und undefined in QueryBuilder .where()

Da QueryBuilder eine Low-Level-API ist, werden null- und undefined-Werte nicht validiert oder transformiert. Ihr Verhalten zu verstehen ist wichtig, um unerwartete Ergebnisse zu vermeiden.

null in QueryBuilder .where()

Wenn null als Wert in einem objektbasierten .where() übergeben wird, generiert es eine SQL-Gleichheitsprüfung gegen NULL:

await dataSource
.createQueryBuilder(Post, "post")
.where({ text: null })
.getMany()
// Generates: WHERE post.text = NULL

In SQL ist column = NULL immer false – nichts gleicht NULL. Diese Abfrage gibt null Ergebnisse zurück, was fast sicher nicht deine Absicht war. Um NULL-Werte abzugleichen, verwende den IsNull()-Operator:

import { IsNull } from "typeorm"

await dataSource
.createQueryBuilder(Post, "post")
.where({ text: IsNull() })
.getMany()
// Generates: WHERE post.text IS NULL

Oder verwende eine String-Bedingung:

await dataSource
.createQueryBuilder(Post, "post")
.where("post.text IS NULL")
.getMany()

undefined in QueryBuilder .where()

Bei undefined als Wert gilt dasselbe Verhalten – es generiert WHERE column = NULL, was immer false ist:

await dataSource
.createQueryBuilder(Post, "post")
.where({ text: undefined })
.getMany()
// Generates: WHERE post.text = NULL
// Returns: zero results

Zusammenfassungstabelle

ValueHigh-level API (find/repository/manager)QueryBuilder .where()
null with "ignore"Property skipped — no filterWHERE col = NULL — zero results
null with "sql-null"WHERE col IS NULLWHERE col = NULL — zero results
null with "throw" (default)Throws errorWHERE col = NULL — zero results
undefined with "ignore"Property skipped — no filterWHERE col = NULL — zero results
undefined with "throw" (default)Throws errorWHERE col = NULL — zero results
IsNull()WHERE col IS NULLWHERE col IS NULL
Tipp

Verwende immer IsNull(), wenn du SQL-NULL-Werte abgleichen möchtest – unabhängig von der verwendeten API. Es funktioniert korrekt in High-Level- und QueryBuilder-Kontexten.