Skip to content

Commit

Permalink
fix: wrong entity transform of relation id when referenced column is …
Browse files Browse the repository at this point in the history
…a primary key (#8959)

* fix: wrong entity transform of relation id when referenced column is also a primary key

* simplified test

Co-authored-by: Christian Forgács <christian@wunderbit.de>
Co-authored-by: Umed Khudoiberdiev <pleerock.me@gmail.com>
  • Loading branch information
3 people authored Jun 29, 2022
1 parent a748f3c commit 6e888dd
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,10 @@ export class RawSqlResultsToEntityTransformer {
column.createValueMap(value),
)
}
if (column.referencedColumn!.referencedColumn) {
if (
!column.isPrimary &&
column.referencedColumn!.referencedColumn
) {
// if column is a relation
value =
column.referencedColumn!.referencedColumn!.createValueMap(
Expand Down
30 changes: 30 additions & 0 deletions test/github-issues/8892/entity/city.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {
Column,
Entity,
JoinTable,
ManyToMany,
PrimaryGeneratedColumn,
RelationId,
} from "../../../../src"
import { Zip } from "./zip"

@Entity()
export class City {
@PrimaryGeneratedColumn()
id: number

@Column()
caption: string

@RelationId((city: City) => city.zips)
zipCodes: {
countryCode: string
zipCode: string
}[]

@ManyToMany(() => Zip, (zip) => zip.cities, {
// cascade: true,
})
@JoinTable()
zips: Zip[]
}
14 changes: 14 additions & 0 deletions test/github-issues/8892/entity/country.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Column, Entity, OneToMany, PrimaryColumn } from "../../../../src"
import { Zip } from "./zip"

@Entity()
export class Country {
@PrimaryColumn({ length: 2 })
code: string

@Column()
caption: string

@OneToMany(() => Zip, (zip) => zip.country)
zips: Zip[]
}
18 changes: 18 additions & 0 deletions test/github-issues/8892/entity/zip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { City } from "./city"
import { Entity, ManyToMany, ManyToOne, PrimaryColumn } from "../../../../src"
import { Country } from "./country"

@Entity()
export class Zip {
@PrimaryColumn({ length: 2 })
countryCode: string

@ManyToOne(() => Country, (country) => country.zips)
country: Country

@PrimaryColumn()
code: string

@ManyToMany(() => City, (city: City) => city.zips)
cities: City[]
}
81 changes: 81 additions & 0 deletions test/github-issues/8892/issue-8892.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import "../../utils/test-setup"
import {
closeTestingConnections,
createTestingConnections,
} from "../../utils/test-utils"
import { expect } from "chai"
import { City } from "./entity/city"
import { Zip } from "./entity/zip"
import { Country } from "./entity/country"
import { DataSource } from "../../../src"

describe('github issues > #8892 ManyToMany relations save throws "Violation of PRIMARY KEY constraint"', async () => {
let connections: DataSource[]

beforeEach(async () => {
connections = await createTestingConnections({
entities: [__dirname + "/entity/*{.js,.ts}"],
schemaCreate: true,
dropSchema: true,
})
})
afterEach(() => closeTestingConnections(connections))

it("should work perfectly with with many to many relation with primary key from related object is a primary key from an many to one relation", async () =>
await Promise.all(
connections.map(async (connection) => {
const cityRepository = connection.getRepository(City)
const countryRepository = connection.getRepository(Country)

const country = new Country()
country.code = "de"
country.caption = "Germany"

const city = new City()
city.caption = "Test city"

const zip1 = new Zip()
zip1.countryCode = "de"
zip1.code = "12345"

const zip2 = new Zip()
zip2.countryCode = "de"
zip2.code = "54321"

await countryRepository.save(country)
await cityRepository.save(city)

const zipRepository = connection.getRepository(Zip)
await zipRepository.save(zip1)
await zipRepository.save(zip2)

await cityRepository.save({
id: city.id,
zips: [zip1, zip2],
})

await cityRepository.save({
id: city.id,
zips: [zip2],
})

const existingCity = await cityRepository.find({
where: {
id: city.id,
},
relations: {
zips: true,
},
})

if (!existingCity.length) throw new Error("city not found")

expect(existingCity[0].zips.length).to.deep.equal(1)
expect(existingCity[0].zips[0].code).to.deep.equal(zip2.code)
expect(existingCity[0].zipCodes[0]).to.deep.equal({
countryCode: zip2.countryCode,
code: zip2.code,
})
}),
))
})

0 comments on commit 6e888dd

Please sign in to comment.