typeorm: JoinTable query generates incorrectly when entity doesn't match standard naming conventions
Steps to reproduce or a small repository showing the problem:
-
Create two entities that don’t follow the naming convention (ex.
Thingin tablethingsandTagin tabletags) -
Create a join table for them (
thing_tags) (note that due to the departure from naming convention earlier, this is also a departure from naming convention) -
Create a
@ManyToManyrelation using@JoinTableinsideThingas follows:
@ManyToMany(type => Tag, {eager: true})
@JoinTable({
name: "thing_tags",
joinColumn: {name: "thing_id", referencedColumnName: "id"}
inverseJoinColumn: {name: "tag_id", referencedColumnName: "id"}
})
tags: Tag[];
When trying to retrieve a Thing, the query is just barely wrong:
SELECT Thing_tags_relation_id.tag_id AS "tag_id", Thing_tags_relation_id.thing_id AS "thing_id" FROM "tags" "tags" INNER JOIN "thing_tags" "Thing_tags_relation_id" ON (Thing_tags_relation_id.thing_id = $1 AND Thing_tags_relation_id.tag_id = "tags"."id") ORDER BY Thing_tags_relation_id.tag_id ASC, Thing_tags_relation_id.thing_id ASC;
ERROR: missing FROM-clause entry for table "thing_tags_relation_id"
The problem here is that Thing_tags_relation_id is not quoted everywhere it’s mentioned. If I take the query to postgres, and add quotes around every unquoted Thing_tags_relation_id, the query works great:
db_test=# SELECT "Thing_tags_relation_id".tag_id AS "tag_id", "Thing_tags_relation_id".thing_id AS "thing_id" FROM "tags" "tags" INNER JOIN "thing_tags" "Thing_tags_relation_id" ON ("Thing_tags_relation_id".thing_id = 1743 AND "Thing_tags_relation_id".tag_id = "tags". "id") ORDER BY "Thing_tags_relation_id".tag_id ASC, "Thing_tags_relation_id".thing_id ASC;
tag_id | thing_id
--------+-----------
(0 rows)
PS I personally would love a parametrizedQuery parameter in error reports that prints the complete query with params filled out (exactly as it would have been sent).
As always thanks for all the work on typeorm, it is 100% improving the development lives of me and my team 😃
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 3
- Comments: 32 (10 by maintainers)
Started implementing the above. Seems to fix this specific problem - running against the test suite to verify it doesn’t break any other cases.
There’s a number of places that require refactoring, though, because they use
referencedColumnand don’t know the relation they’re associated with.In some cases, the code paths are RELYING on this behavior so they don’t crash. (They just did the wrong thing before)
Was thinking it through finding all the related issues.
Path forward can be as such -
referencedColumnhas to be marked deprecated. No matter what, this just doesn’t work, the data modelling doesn’t match up with reality.😭 There goes my hopes of a one line fix.
Any update on this?
Ok, after digging around some more I realized why I am getting this incorrect query. It’s basically because typeorm assumes that a single column will always only be used to reference a single table with a specific referenced column. If you now have a
fooIdrelation that refers tofoo.idandsomefoolinktable.foo_idby setting up custom JoinColumn decorations with referencedColumnNames you get an incorrect query because one relation will override the referencedColumn offooIdthat was previously written by the other.I’m not sure whether this actually is what the original issue poster was experiencing through another pathway.
Does it sound like it would make sense to change the referencedColumns of ColumnMetadata to be
ColumnMetadataArray instead of just single metadata? I think I will try my hand at making this change but just wanted to check if someone already knew whether it makes sense.Are there any suggested workarounds for this? (Specifically ones using
find, and notcreateQueryBuilder?)I can provide a full repro, but it sounds like the issue is well understood. Basically, in our case, a
ProjectRolehas aUserand aProject, throughuser_idand aproject_id, respectively, and it also has aProjectLabel, with a multi-keyJoinColumnof:Here is the relevant section of the generated query for our issue:
Here,
ON ProjectRole__user.useridshould beON "ProjectRole__user"."id", andON ProjectRole__project.projectidshould beON "ProjectRole__project"."id". Also, note that if I remove the (multi-column)ProjectLabelrelation, this problem goes away.It definitely seems like the case of having multiple join columns with the same
name, but different join tables.Just ran into this as well. @pleerock could we get this reopened?