diff --git a/src/entity-manager/EntityManager.ts b/src/entity-manager/EntityManager.ts index cd97824e0a..f06cda92ca 100644 --- a/src/entity-manager/EntityManager.ts +++ b/src/entity-manager/EntityManager.ts @@ -1088,6 +1088,12 @@ export class EntityManager { alias = options.join.alias } + if (!options.where) { + throw new Error( + `You must provide selection conditions in order to find a single row.`, + ) + } + // create query builder and apply find options return this.createQueryBuilder(entityClass, alias) .setFindOptions({ diff --git a/src/repository/BaseEntity.ts b/src/repository/BaseEntity.ts index e80a2837ce..32fba60c24 100644 --- a/src/repository/BaseEntity.ts +++ b/src/repository/BaseEntity.ts @@ -80,11 +80,17 @@ export class BaseEntity { */ async reload(): Promise { const baseEntity = this.constructor as typeof BaseEntity - const newestEntity: BaseEntity = await baseEntity + const id = baseEntity.getRepository().metadata.getEntityIdMap(this) + if (!id) { + throw new Error( + `Entity doesn't have id-s set, cannot reload entity`, + ) + } + const reloadedEntity: BaseEntity = await baseEntity .getRepository() - .findOneOrFail(baseEntity.getId(this)) + .findOneByOrFail(id) - ObjectUtils.assign(this, newestEntity) + ObjectUtils.assign(this, reloadedEntity) } // ------------------------------------------------------------------------- diff --git a/test/functional/entity-model/entity-model.ts b/test/functional/entity-model/entity-model.ts index 4adb7e719b..392a27dcf3 100644 --- a/test/functional/entity-model/entity-model.ts +++ b/test/functional/entity-model/entity-model.ts @@ -1,4 +1,4 @@ -import "reflect-metadata" +import "../../utils/test-setup" import { Post } from "./entity/Post" import { Category } from "./entity/Category" import { @@ -6,7 +6,7 @@ import { createTestingConnections, reloadTestingDatabases, } from "../../utils/test-utils" -import { DataSource } from "../../../src/data-source/DataSource" +import { DataSource } from "../../../src" describe("entity-model", () => { let connections: DataSource[] @@ -117,4 +117,53 @@ describe("entity-model", () => { }) } }) + + it("should reload exactly the same entity", async () => { + // These must run sequentially as we have the global context of the `Post` ActiveRecord class + for (const connection of connections) { + await connection.synchronize(true) + Post.useDataSource(connection) + Category.useDataSource(connection) + + const post1 = Post.create() + post1.title = "About ActiveRecord 1" + post1.externalId = "some external id 1" + await post1.save() + + post1.should.be.eql({ + id: 1, + title: "About ActiveRecord 1", + text: "This is default text.", + externalId: "some external id 1", + }) + await post1.reload() + + post1.should.be.eql({ + id: 1, + title: "About ActiveRecord 1", + text: "This is default text.", + externalId: "some external id 1", + }) + + const post2 = Post.create() + post2.title = "About ActiveRecord 2" + post2.externalId = "some external id 2" + await post2.save() + + post2.should.be.eql({ + id: 2, + title: "About ActiveRecord 2", + text: "This is default text.", + externalId: "some external id 2", + }) + await post2.reload() + + post2.should.be.eql({ + id: 2, + title: "About ActiveRecord 2", + text: "This is default text.", + externalId: "some external id 2", + }) + } + }) }) diff --git a/test/functional/entity-model/entity/Category.ts b/test/functional/entity-model/entity/Category.ts index d142ac1203..dad5a70c45 100644 --- a/test/functional/entity-model/entity/Category.ts +++ b/test/functional/entity-model/entity/Category.ts @@ -1,7 +1,4 @@ -import { PrimaryColumn } from "../../../../src/decorator/columns/PrimaryColumn" -import { Entity } from "../../../../src/decorator/entity/Entity" -import { BaseEntity } from "../../../../src/repository/BaseEntity" -import { Column } from "../../../../src/decorator/columns/Column" +import { BaseEntity, Column, Entity, PrimaryColumn } from "../../../../src" @Entity() export class Category extends BaseEntity { diff --git a/test/functional/entity-model/entity/Post.ts b/test/functional/entity-model/entity/Post.ts index 5b0821f85e..48c8eceeb5 100644 --- a/test/functional/entity-model/entity/Post.ts +++ b/test/functional/entity-model/entity/Post.ts @@ -1,8 +1,11 @@ -import { Entity } from "../../../../src/decorator/entity/Entity" -import { BaseEntity } from "../../../../src/repository/BaseEntity" -import { PrimaryGeneratedColumn } from "../../../../src/decorator/columns/PrimaryGeneratedColumn" -import { Column } from "../../../../src/decorator/columns/Column" -import { JoinTable, ManyToMany } from "../../../../src" +import { + BaseEntity, + Column, + Entity, + JoinTable, + ManyToMany, + PrimaryGeneratedColumn, +} from "../../../../src" import { Category } from "./Category" @Entity() diff --git a/test/functional/relations/multiple-primary-keys/multiple-primary-keys-one-to-many/multiple-primary-keys-one-to-many.ts b/test/functional/relations/multiple-primary-keys/multiple-primary-keys-one-to-many/multiple-primary-keys-one-to-many.ts index e277e12b2f..fe5792d4de 100644 --- a/test/functional/relations/multiple-primary-keys/multiple-primary-keys-one-to-many/multiple-primary-keys-one-to-many.ts +++ b/test/functional/relations/multiple-primary-keys/multiple-primary-keys-one-to-many/multiple-primary-keys-one-to-many.ts @@ -57,7 +57,7 @@ describe("relations > multiple-primary-keys > one-to-many", () => { connections.map(async (connection) => { await insertSimpleTestData(connection) - const user = await connection.getRepository(User).findOne({ + const [user] = await connection.getRepository(User).find({ relations: ["settings"], // relationLoadStrategy: "join" }) @@ -84,9 +84,9 @@ describe("relations > multiple-primary-keys > one-to-many", () => { }, ]) - const user = await connection + const [user] = await connection .getRepository(User) - .findOne({ relations: ["settings"] }) + .find({ relations: ["settings"] }) // check the saved items have correctly updated value expect(user!).not.to.be.undefined @@ -116,7 +116,7 @@ describe("relations > multiple-primary-keys > one-to-many", () => { settings: [], }) - const user = await connection.getRepository(User).findOne({ + const [user] = await connection.getRepository(User).find({ relations: ["settings"], }) diff --git a/test/functional/repository/find-methods/repostiory-find-methods.ts b/test/functional/repository/find-methods/repostiory-find-methods.ts index 826071b2ef..5ec3632b07 100644 --- a/test/functional/repository/find-methods/repostiory-find-methods.ts +++ b/test/functional/repository/find-methods/repostiory-find-methods.ts @@ -375,7 +375,7 @@ describe("repository > find methods", () => { }) describe("findOne", function () { - it("should return first when no criteria given", () => + it("should throw an error when no criteria given", () => Promise.all( connections.map(async (connection) => { const userRepository = @@ -390,12 +390,13 @@ describe("repository > find methods", () => { await userRepository.save(user) } - const loadedUser = (await userRepository.findOne({ - order: { id: "ASC" }, - }))! - loadedUser.id.should.be.equal(0) - loadedUser.firstName.should.be.equal("name #0") - loadedUser.secondName.should.be.equal("Doe") + return userRepository + .findOne({ + order: { id: "ASC" }, + }) + .should.be.rejectedWith( + `You must provide selection conditions in order to find a single row.`, + ) }), )) diff --git a/test/functional/repository/find-options-locking/find-options-locking.ts b/test/functional/repository/find-options-locking/find-options-locking.ts index 4532920f7e..f73df35869 100644 --- a/test/functional/repository/find-options-locking/find-options-locking.ts +++ b/test/functional/repository/find-options-locking/find-options-locking.ts @@ -465,6 +465,7 @@ describe("repository > find options > locking", () => { entityManager .getRepository(Post) .findOne({ + where: { id: 1 }, lock: { mode: "pessimistic_write", tables: [] }, }) .should.be.rejectedWith( @@ -491,6 +492,7 @@ describe("repository > find options > locking", () => { entityManager .getRepository(Post) .findOne({ + where: { id: 1 }, relations: ["author"], lock: { mode: "pessimistic_write", @@ -512,6 +514,7 @@ describe("repository > find options > locking", () => { return connection.manager.transaction((entityManager) => { return Promise.all([ entityManager.getRepository(Post).findOne({ + where: { id: 1 }, relations: ["author"], lock: { mode: "pessimistic_write", @@ -530,6 +533,7 @@ describe("repository > find options > locking", () => { return connection.manager.transaction((entityManager) => { return Promise.all([ entityManager.getRepository(Post).findOne({ + where: { id: 1 }, relations: ["author"], lock: { mode: "pessimistic_write", @@ -539,6 +543,7 @@ describe("repository > find options > locking", () => { entityManager .getRepository(Post) .findOne({ + where: { id: 1 }, relations: ["author"], lock: { mode: "pessimistic_write" }, }) @@ -561,6 +566,7 @@ describe("repository > find options > locking", () => { return connection.manager.transaction((entityManager) => { return Promise.all([ entityManager.getRepository(Post).findOne({ + where: { id: 1 }, relations: ["author"], lock: { mode: "pessimistic_read", @@ -568,6 +574,7 @@ describe("repository > find options > locking", () => { }, }), entityManager.getRepository(Post).findOne({ + where: { id: 1 }, relations: ["author"], lock: { mode: "pessimistic_write", @@ -575,6 +582,7 @@ describe("repository > find options > locking", () => { }, }), entityManager.getRepository(Post).findOne({ + where: { id: 1 }, relations: ["author"], lock: { mode: "pessimistic_partial_write", @@ -582,6 +590,7 @@ describe("repository > find options > locking", () => { }, }), entityManager.getRepository(Post).findOne({ + where: { id: 1 }, relations: ["author"], lock: { mode: "pessimistic_write_or_fail", @@ -589,6 +598,7 @@ describe("repository > find options > locking", () => { }, }), entityManager.getRepository(Post).findOne({ + where: { id: 1 }, relations: ["author"], lock: { mode: "for_no_key_update", @@ -614,6 +624,7 @@ describe("repository > find options > locking", () => { return connection.manager.transaction((entityManager) => { return Promise.all([ entityManager.getRepository(Post).findOne({ + where: { id: 1 }, join: { alias: "post", innerJoinAndSelect: { diff --git a/test/functional/repository/find-options/repository-find-options.ts b/test/functional/repository/find-options/repository-find-options.ts index d3191e279c..d71a1b26a5 100644 --- a/test/functional/repository/find-options/repository-find-options.ts +++ b/test/functional/repository/find-options/repository-find-options.ts @@ -44,11 +44,9 @@ describe("repository > find options", () => { post.categories = [category] await connection.manager.save(post) - const loadedPost = await connection - .getRepository(Post) - .findOne({ - relations: ["author", "categories"], - }) + const [loadedPost] = await connection.getRepository(Post).find({ + relations: ["author", "categories"], + }) expect(loadedPost).to.be.eql({ id: 1, title: "About Alex Messer", diff --git a/test/functional/table-inheritance/single-table/no-type-column/no-type-column.ts b/test/functional/table-inheritance/single-table/no-type-column/no-type-column.ts index 849547b07b..49154f1524 100644 --- a/test/functional/table-inheritance/single-table/no-type-column/no-type-column.ts +++ b/test/functional/table-inheritance/single-table/no-type-column/no-type-column.ts @@ -54,17 +54,17 @@ describe("table-inheritance > single-table > no-type-column", () => { // Select // ------------------------------------------------------------------------- - const postIt = (await postItRepo.findOne({ + const [postIt] = await postItRepo.find({ relations: ["owner"], - })) as PostItNote + }) postIt.owner.should.be.an.instanceOf(Employee) postIt.owner.name.should.be.equal("alicefoo") postIt.owner.employeeName.should.be.equal("Alice Foo") - const sticky = (await stickyRepo.findOne({ + const [sticky] = await stickyRepo.find({ relations: ["owner"], - })) as StickyNote + }) sticky.owner.should.be.an.instanceOf(Author) sticky.owner.name.should.be.equal("bobbar") diff --git a/test/github-issues/1720/issue-1720.ts b/test/github-issues/1720/issue-1720.ts index f4b8f0e117..f876bb89e7 100755 --- a/test/github-issues/1720/issue-1720.ts +++ b/test/github-issues/1720/issue-1720.ts @@ -36,7 +36,7 @@ describe("github issues > #1720 Listener not invoked when relation loaded throug post1.categories = [category1, category2] await connection.manager.save(post1) - const loadedPost = await connection.manager.findOne(Post, { + const [loadedPost] = await connection.manager.find(Post, { relations: ["categories"], }) loadedPost!.categories[0].loaded.should.be.equal(true) diff --git a/test/github-issues/3118/issue-3118.ts b/test/github-issues/3118/issue-3118.ts index 669dee3fe3..1c7ff8fef7 100644 --- a/test/github-issues/3118/issue-3118.ts +++ b/test/github-issues/3118/issue-3118.ts @@ -76,7 +76,7 @@ describe("github issues > #3118 shorten alias names (for RDBMS with a limit) whe .save(category) } - const loadedCategory = await connection.manager.findOne( + const [loadedCategory] = await connection.manager.find( CategoryWithVeryLongName, { relations: [ diff --git a/test/github-issues/7932/issue-7932.ts b/test/github-issues/7932/issue-7932.ts index 3ac0b7bc0d..f1957b735d 100644 --- a/test/github-issues/7932/issue-7932.ts +++ b/test/github-issues/7932/issue-7932.ts @@ -31,7 +31,7 @@ describe("github issues > #7932 non-ascii characters assigned to var/char colum entity.fixedLengthContent = "\u2022" await repo.save(entity) - const savedEntity = await repo.findOne({ + const [savedEntity] = await repo.find({ order: { created: "DESC" }, })