-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Description
Issue description
If you have 3 tables, where;
- Table 1 has a unique PK, and JOIN references to Table 2 (using
table1.table_2_key => table2.key,table1.table_3_key => table2.table_3_key) and Table 3 (usingtable1.table_3_key => table3.key) - Table 2 has a compound PK of (
key, table_3_key), and JOIN references to Table 3 (usingtable2.table_3_key => table3.key) - Table 3 has a unique PK (
key), and references to nothing.
Invalid SQL will be generated by TypeORM on findOne() but not on syncronize
Expected Behavior
All camelCase variables to be replaced with their snake_case/table definition names
Actual Behavior
Some fields are not properly replaced, or possibly not properly looked up from their source tables
Steps to reproduce
export abstract class Basics {
@ManyToOne(() => Groups)
@JoinColumn({ name: 'group_key' })
group?: Groups;
@Column({ name: 'group_key', length: 70, nullable: true })
groupKey: string;
@ManyToOne(() => Rounds, (round) => round.key)
@JoinColumn([
{ name: 'round_key', referencedColumnName: 'key' },
{ name: 'group_key', referencedColumnName: 'groupKey' },
])
round?: Rounds;
@Column({ name: 'round_key', length: 70, nullable: true })
roundKey: string;
}@Entity({
name: 'rounds',
})
export class Rounds {
@PrimaryColumn({ name: 'key', length: 70, type: 'varchar' })
key: string;
@Column({ name: 'name', length: 100, type: 'varchar' })
name: string;
@ManyToOne(() => Groups, (group) => group.key)
@JoinColumn({ name: 'group_key' })
group?: Groups;
@PrimaryColumn({ name: 'group_key' })
groupKey: string;
}@Entity({
name: 'groups',
})
export class Groups {
@PrimaryColumn({ name: 'key', length: 70, type: 'varchar' })
key: string;
@Column({ name: 'name', length: 70, type: 'varchar' })
name: string;
@Column({ name: 'type', length: 20, type: 'varchar' })
type: GroupType;
@OneToMany(() => Rounds, (round) => round.group)
rounds: Rounds[];
}export abstract class Basics {
@ManyToOne(() => Groups)
@JoinColumn({ name: 'group_key', referencedColumnName: 'key' })
group?: Groups;
@Column({ name: 'group_key', length: 70, nullable: true })
groupKey: string;
@ManyToOne(() => Rounds)
@JoinColumn([
{ name: 'round_key', referencedColumnName: 'key' },
{ name: 'group_key', referencedColumnName: 'groupKey' },
])
round?: Rounds;
@Column({ name: 'round_key', length: 70, nullable: true })
roundKey: string;
}
@Entity({
name: 'servers',
})
export class Servers extends Basics {
@PrimaryColumn({ name: 'uuid', length: 36, type: 'varchar' })
uuid: string;
} const serverData = await conn.getRepository(Servers).findOne({ where: { uuid }, relations: ['group', 'round'] });My Environment
| Dependency | Version |
|---|---|
| Operating System | Linux |
| Node.js version | v16.17.0 |
| TypeORM version | 0.3.17 |
Additional Context
This issue was introduced, I believe, because a join to Rounds has a compound primary key that uses a column name shared with another table join.
Setting the JoinColumn to key or group_key or anything of the sort, causes it to fail to come online when syncronize: true is set. So; for whatever reason, the camelCase groupKey is valid. However, having more than one JoinColumn definition for the same name causes TypeORM to get confused.
Once the SQL is generated for the request, it does properly replace groupKey with group_key for the rounds join, but NOT for the groups join, it produces
LEFT JOIN `groups` `Servers__Servers_group` ON Servers__Servers_group.groupKey = `Servers`.`group_key`
LEFT JOIN `rounds` `Servers__Servers_round` ON `Servers__Servers_round`.`key` = `Servers`.`round_key` AND `Servers__Servers_round`.`group_key` = `Servers`.`group_key` The FKs and Indexes are all generated as expected, with composite primary keys. The only thing that does not generate properly is the SQL on SELECT.
Removing the extra item from the JoinColumn definition causes the FKs and Indexes to be generated incorrectly
ALTER TABLE `servers` ADD CONSTRAINT `FK_821...` FOREIGN KEY (`round_key`, `round_key`) REFERENCES `rounds`(`key`,`group_key`)and in turn can cause SQL to throw a duplicate column error.
There seems to be a lack of documentation on exactly what I should be doing here, probably because it is an edge case. But if you edit the SQL manually to have the correct value of just key and run it, it does work as expected. My database explorer tools also seem capable of generating queries correctly based on this scenario and the FK/Index setup that TypeORM generates in this configuration.
Relevant Database Driver(s)
- aurora-mysql
- aurora-postgres
- better-sqlite3
- cockroachdb
- cordova
- expo
- mongodb
- mysql
- nativescript
- oracle
- postgres
- react-native
- sap
- spanner
- sqlite
- sqlite-abstract
- sqljs
- sqlserver
Are you willing to resolve this issue by submitting a Pull Request?
Yes, I have the time, but I don't know how to start. I would need guidance.