Skip to content

Commit f8c52f3

Browse files
author
Lovro Puzar
authored
fix: calling EntityManager.insert() with an empty array of entities (#5745)
As described in issue #5734, the current behaviour seems like an oversight and inconsistent with save() and remove() which already have this handled as a special case. Test Plan: npm test, and more specifically npm test -- --grep='#5734' Closes: #5734
1 parent 7d8a1ca commit f8c52f3

File tree

4 files changed

+72
-0
lines changed

4 files changed

+72
-0
lines changed

src/entity-manager/EntityManager.ts

+10
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,16 @@ export class EntityManager {
582582
*/
583583
async insert<Entity>(target: ObjectType<Entity>|EntitySchema<Entity>|string, entity: QueryDeepPartialEntity<Entity>|(QueryDeepPartialEntity<Entity>[])): Promise<InsertResult> {
584584

585+
// If user passed empty array of entities then we don't need to do
586+
// anything.
587+
//
588+
// Fixes GitHub issue #5734. If we were to let this through we would
589+
// run into problems downstream, like subscribers getting invoked with
590+
// the empty array where they expect an entity, and SQL queries with an
591+
// empty VALUES clause.
592+
if (Array.isArray(entity) && entity.length === 0)
593+
return Promise.resolve(new InsertResult());
594+
585595
// TODO: Oracle does not support multiple values. Need to create another nice solution.
586596
if (this.connection.driver instanceof OracleDriver && Array.isArray(entity)) {
587597
const results = await Promise.all(entity.map(entity => this.insert(target, entity)));
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {PrimaryColumn} from "../../../../src/decorator/columns/PrimaryColumn";
2+
import {Entity} from "../../../../src/decorator/entity/Entity";
3+
4+
@Entity()
5+
export class Post {
6+
@PrimaryColumn()
7+
id: number;
8+
9+
constructor(id: number) {
10+
this.id = id;
11+
}
12+
}

test/github-issues/5734/issue-5734.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import "reflect-metadata";
2+
import {closeTestingConnections, createTestingConnections, reloadTestingDatabases} from "../../utils/test-utils";
3+
import {Connection} from "../../../src/connection/Connection";
4+
import {Post} from "./entity/Post";
5+
6+
describe("github issues > #5734 insert([]) should not crash", () => {
7+
8+
let connections: Connection[];
9+
before(async () => connections = await createTestingConnections({
10+
entities: [__dirname + "/entity/*{.js,.ts}"],
11+
subscribers: [__dirname + "/subscriber/*{.js,.ts}"],
12+
schemaCreate: true,
13+
dropSchema: true
14+
}));
15+
beforeEach(() => reloadTestingDatabases(connections));
16+
after(() => closeTestingConnections(connections));
17+
18+
it("should not crash on insert([])", () => Promise.all(connections.map(async connection => {
19+
const repository = connection.getRepository(Post);
20+
await repository.insert([]);
21+
})));
22+
23+
it("should still work with a nonempty array", () => Promise.all(connections.map(async connection => {
24+
const repository = connection.getRepository(Post);
25+
await repository.insert([new Post(1)]);
26+
await repository.findOneOrFail({where: {id: 1}});
27+
})));
28+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import {Post} from "../entity/Post";
2+
import {EntitySubscriberInterface, EventSubscriber, InsertEvent} from "../../../../src";
3+
4+
/**
5+
* Subscriber which checks the validity of the entity passed to beforeInsert().
6+
* Tests the fix for issue #5734 in which we saw an empty array leak into
7+
* beforeInsert().
8+
*/
9+
@EventSubscriber()
10+
export class ValidEntityCheckSubscriber
11+
implements EntitySubscriberInterface<Post> {
12+
listenTo() {
13+
return Post;
14+
}
15+
16+
beforeInsert(event: InsertEvent<Post>) {
17+
const entity = event.entity;
18+
if (Array.isArray(entity) || !entity.id) {
19+
throw new Error(`Subscriber saw invalid entity: ${JSON.stringify(entity)}`);
20+
}
21+
}
22+
}

0 commit comments

Comments
 (0)