diff --git a/src/entity-manager/EntityManager.ts b/src/entity-manager/EntityManager.ts
index 213dfe915d..2168d3f4dc 100644
--- a/src/entity-manager/EntityManager.ts
+++ b/src/entity-manager/EntityManager.ts
@@ -700,7 +700,9 @@ export class EntityManager {
}
const conflictColumns = metadata.mapPropertyPathsToColumns(
- options.conflictPaths,
+ Array.isArray(options.conflictPaths)
+ ? options.conflictPaths
+ : Object.keys(options.conflictPaths),
)
const overwriteColumns = metadata.columns.filter(
diff --git a/src/repository/UpsertOptions.ts b/src/repository/UpsertOptions.ts
index 6f138eb18a..4e7a7f8825 100644
--- a/src/repository/UpsertOptions.ts
+++ b/src/repository/UpsertOptions.ts
@@ -3,7 +3,7 @@
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export interface UpsertOptions {
- conflictPaths: string[]
+ conflictPaths: string[] | { [P in keyof Entity]?: true }
/**
* If true, postgres will skip the update if no values would be changed (reduces writes)
*/
diff --git a/test/github-issues/9412/entity/Post.ts b/test/github-issues/9412/entity/Post.ts
new file mode 100644
index 0000000000..edad7e2301
--- /dev/null
+++ b/test/github-issues/9412/entity/Post.ts
@@ -0,0 +1,15 @@
+import { Entity } from "../../../../src/decorator/entity/Entity"
+import { PrimaryGeneratedColumn } from "../../../../src/decorator/columns/PrimaryGeneratedColumn"
+import { Column } from "../../../../src/decorator/columns/Column"
+
+@Entity()
+export class Post {
+ @PrimaryGeneratedColumn()
+ id: number
+
+ @Column({unique: true})
+ title: string
+
+ @Column({unique: true})
+ author: string
+}
diff --git a/test/github-issues/9412/issue-9412.ts b/test/github-issues/9412/issue-9412.ts
new file mode 100644
index 0000000000..441da4730e
--- /dev/null
+++ b/test/github-issues/9412/issue-9412.ts
@@ -0,0 +1,46 @@
+import 'reflect-metadata'
+import {
+ closeTestingConnections,
+ createTestingConnections,
+ reloadTestingDatabases,
+} from '../../utils/test-utils'
+import { DataSource } from '../../../src/data-source/DataSource'
+import { Post } from './entity/Post'
+import { expect } from 'chai'
+
+describe('github issues > #9365 ', () => {
+ let connections: DataSource[]
+ before(
+ async () =>
+ (connections = await createTestingConnections({
+ entities: [ __dirname + '/entity/*{.js,.ts}' ],
+ enabledDrivers: [ 'postgres' ],
+ })),
+ )
+ beforeEach(() => reloadTestingDatabases(connections))
+ after(() => closeTestingConnections(connections))
+
+ it('should work with conflict path', () =>
+ Promise.all(
+ connections.map(async (connection) => {
+ const postRepository = connection.getRepository(Post)
+
+ const post1 = new Post()
+ post1.title = 'Test1'
+ post1.author = 'Test1'
+ await postRepository.save(post1)
+
+ const post2 = new Post()
+ post2.title = 'Test'
+ post2.author = 'Test2'
+
+ await postRepository.upsert(post2, { conflictPaths: { author: true }, skipUpdateIfNoValuesChanged: true })
+ const allPostsAfterUpsert1= await postRepository.find()
+ expect(allPostsAfterUpsert1.length).equal(2)
+
+ await postRepository.upsert(post2, { conflictPaths: { title: true }, skipUpdateIfNoValuesChanged: true })
+ const allPostsAfterUpsert2= await postRepository.find()
+ expect(allPostsAfterUpsert2.length).equal(2)
+ }),
+ ))
+})