-
-
Notifications
You must be signed in to change notification settings - Fork 544
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core): allow disabling identity map and change set tracking (#1307)
Sometimes we might want to disable identity map and change set tracking for some query. This is possible via `disableIdentityMap` option. Behind the scenes, it will create new context, load the entities inside that, and clear it afterwards, so the main identity map will stay clean. ```ts const users = await orm.em.find(User, { email: '[email protected]' }, { disableIdentityMap: true, populate: { cars: { brand: true } }, }); users[0].name = 'changed'; await orm.em.flush(); // calling flush have no effect, as the entity is not managed ``` > Keep in mind that this can also have > [negative effect on the performance](https://stackoverflow.com/questions/9259480/entity-framework-mergeoption-notracking-bad-performance). Closes #1267
- Loading branch information
Showing
5 changed files
with
89 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -291,6 +291,28 @@ where lower(email) = '[email protected]' | |
order by (point(loc_latitude, loclongitude) <@> point(0, 0)) asc | ||
``` | ||
## Disabling identity map and change set tracking | ||
Sometimes we might want to disable identity map and change set tracking for some query. | ||
This is possible via `disableIdentityMap` option. Behind the scenes, it will create new | ||
context, load the entities inside that, and clear it afterwards, so the main identity map | ||
will stay clean. | ||
> As opposed to _managed_ entities, such entities are called _detached_. | ||
> To be able to work with them, you first need to merge them via `em.registerManaged()`. | ||
```ts | ||
const users = await orm.em.find(User, { email: '[email protected]' }, { | ||
disableIdentityMap: true, | ||
populate: { cars: { brand: true } }, | ||
}); | ||
users[0].name = 'changed'; | ||
await orm.em.flush(); // calling flush have no effect, as the entity is not managed | ||
``` | ||
> Keep in mind that this can also have | ||
> [negative effect on the performance](https://stackoverflow.com/questions/9259480/entity-framework-mergeoption-notracking-bad-performance). | ||
## Type of Fetched Entities | ||
Both `em.find` and `em.findOne()` methods have generic return types. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -661,6 +661,53 @@ describe('EntityManagerSqlite2', () => { | |
expect(book.tags.count()).toBe(0); | ||
}); | ||
|
||
test('disabling identity maap', async () => { | ||
const author = orm.em.create(Author4, { name: 'Jon Snow', email: '[email protected]' }); | ||
const book1 = orm.em.create(Book4, { title: 'My Life on the Wall, part 1', author }); | ||
const book2 = orm.em.create(Book4, { title: 'My Life on the Wall, part 2', author }); | ||
const book3 = orm.em.create(Book4, { title: 'My Life on the Wall, part 3', author }); | ||
const tag1 = orm.em.create(BookTag4, { name: 'silly' }); | ||
const tag2 = orm.em.create(BookTag4, { name: 'funny' }); | ||
const tag3 = orm.em.create(BookTag4, { name: 'sick' }); | ||
const tag4 = orm.em.create(BookTag4, { name: 'strange' }); | ||
const tag5 = orm.em.create(BookTag4, { name: 'sexy' }); | ||
book1.tags.add(tag1, tag3); | ||
book2.tags.add(tag1, tag2, tag5); | ||
book3.tags.add(tag2, tag4, tag5); | ||
|
||
orm.em.persist(book1); | ||
orm.em.persist(book2); | ||
await orm.em.persist(book3).flush(); | ||
orm.em.clear(); | ||
|
||
const authors = await orm.em.find(Author4, {}, { | ||
populate: { books: { tags: true } }, | ||
disableIdentityMap: true, | ||
}); | ||
|
||
expect(authors).toHaveLength(1); | ||
expect(authors[0].id).toBe(author.id); | ||
expect(authors[0].books).toHaveLength(3); | ||
expect(authors[0].books[0].id).toBe(book1.id); | ||
expect(authors[0].books[0].tags).toHaveLength(2); | ||
expect(authors[0].books[0].tags[0].name).toBe('silly'); | ||
expect(orm.em.getUnitOfWork().getIdentityMap().values().length).toBe(0); | ||
|
||
const a1 = await orm.em.findOneOrFail(Author4, author.id, { | ||
populate: { books: { tags: true } }, | ||
disableIdentityMap: true, | ||
}); | ||
expect(a1.id).toBe(author.id); | ||
expect(a1.books).toHaveLength(3); | ||
expect(a1.books[0].id).toBe(book1.id); | ||
expect(a1.books[0].tags).toHaveLength(2); | ||
expect(a1.books[0].tags[0].name).toBe('silly'); | ||
expect(orm.em.getUnitOfWork().getIdentityMap().values().length).toBe(0); | ||
|
||
expect(a1).not.toBe(authors[0]); | ||
expect(a1.books[0]).not.toBe(authors[0].books[0]); | ||
}); | ||
|
||
test('populating many to many relation', async () => { | ||
const p1 = orm.em.create(Publisher4, { name: 'foo' }); | ||
expect(p1.tests).toBeInstanceOf(Collection); | ||
|