File tree Expand file tree Collapse file tree 4 files changed +72
-0
lines changed Expand file tree Collapse file tree 4 files changed +72
-0
lines changed Original file line number Diff line number Diff 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 ) ) ) ;
Original file line number Diff line number Diff line change 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+ }
Original file line number Diff line number Diff line change 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 number Diff line number Diff line change 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+ }
You can’t perform that action at this time.
0 commit comments