環境
TLDR
以下、2つの理由で、Entity内で、{ eager: true }
は使わないほうが良いと判断しました。
-
必要のないカラムを取得する場合がある(後述)。
-
Entity内で、
{ eager: true }
をしている時の挙動について、以下の2つの記載がありますが、現時点の挙動としては後者が正しいようです。-
https://github.com/typeorm/typeorm/blob/master/docs/relations.md#relation-options
eager: boolean - If set to true, the relation will always be loaded with the main entity when using find* methods or QueryBuilder on this entity
trueに設定した場合、
find*
メソッド、またはQueryBuilder
を使った時は、リレーションは常にメインエンティティとともにロードされます。-
https://github.com/typeorm/typeorm/blob/master/docs/eager-and-lazy-relations.md#eager-relations
Eager relations only work when you use find* methods. If you use QueryBuilder eager relations are disabled and have to use leftJoinAndSelect to load the relation.
Eager relations は、
find*
メソッドを使用する場合にのみ機能します。QueryBuilder
を使用する場合、Eager relationsは無効になり、leftJoinAndSelect
を使用して関係をロードする必要があります。 -
https://github.com/typeorm/typeorm/blob/master/docs/relations.md#relation-options
検証
以下のような Author has many Books という関連があるとします
@Entity()
export class Work {
@PrimaryGeneratedColumn()
readonly id!: number
@Index()
@ManyToOne(
() => Author,
(author) => author.books
)
author!: Author
@Entity()
export class Author {
@PrimaryGeneratedColumn()
readonly id!: number
@OneToMany(
() => Book,
(book) => book.author,
{ eager: true, cascade: true }
)
books!: Book[]
findを使ったクエリーの結果
this.bookRepository.find({ relations: ['author'] })
Book
を上記の条件で検索した時に、関連するAuthor
だけではなく、更にbooks
もレスポンスに含まれてしまいました({ eager: true }
を設定しているため)。
必要に応じて、leftJoinAndSelect
を指定して、常に意図した結果を得るようにした方が良さそうです。
[
{
"id": 7,
"name": "What book is this?",
"author": {
"id": 6,
"name": "Who am I",
"createdAt": "2020-04-18T01:20:26.810Z",
"updatedAt": "2020-04-18T01:20:26.810Z",
"books": [
{
"id": 7,
"name": "What book is this?",
}
]
}
}
]