JOIN with no results produces entity with nulled properties
See original GitHub issueIssue type:
[x] question [ ] bug report [ ] feature request [ ] documentation issue
Database system/driver:
[ ] cordova
[ ] mongodb
[ ] mssql
[ ] mysql
/ mariadb
[ ] oracle
[x] postgres
[ ] cockroachdb
[ ] sqlite
[ ] sqljs
[ ] react-native
[ ] expo
TypeORM version:
[x] latest
[ ] @next
[ ] 0.x.x
(or put your version here)
First, thank you for providing this amazing ORM to the community. You guys are doing awesome work on this project.
Now, I have an issue with “custom” many-to-many that you hopefully can help me with.
I wanted to have a Many-to-many
relationship setup using TypeORM, but I needed to add some extra properties to the pivot table between them and was therefore not able to use an “automatically” generated pivot table.
Instead, I ended up doing this:
@Entity()
export class User {
...other properties
@OneToMany(type => Participant, participants => participants.user)
events: Array<Participant>;
}
@Entity()
export class Participant {
...other properties
@ManyToOne(type => CalendarEvent, calendarEvent =>
calendarEvent.participants, { primary: true })
event: CalendarEvent;
@ManyToOne(type => User, user => user.events, { primary: true })
user: User;
}
@Entity()
export class CalendarEvent {
...other properties
@OneToMany(type => Participant, participants => participants.event)
participants: Array<Participant>;
}
This works if I left JOIN from either CalendarEvent
to pivot, or from User
to pivot and will produce an empty array if there are no results. But if I left join once more to get the other entity as well, I get a pivot object back where all properties are null.
Joining once:
return this.entityManager.createQueryBuilder(User, "user")
.leftJoinAndSelect("user.events", "pivot")
.where("user.id = :ID", {
ID: "UUID-in-here"
})
.getOne();
It produces empty arrays when there is no results:
{
"id": "UUID-in-here"
"events": []
}
Joining again to retreive the event data:
return this.entityManager.createQueryBuilder(User, "user")
.leftJoinAndSelect("user.events", "pivot")
.leftJoinAndSelect("pivot.event", "event")
.where("user.id = :ID", {
ID: "UUID-in-here"
})
.getOne();
I get the following result:
{
"id": "UUID-in-here"
"events": [
{
...extra pivot columns here with value = null
"event": null
}
]
}
This doesn’t happen if you left JOIN multiple times using “normal” many-to-many relationships. For instance, if I run this:
return this.entityManager.createQueryBuilder(User, "user")
.leftJoinAndSelect("user.teams", "team")
.leftJoinAndSelect("team.messages", "message")
.where("user.id = :ID", {
ID: "UUID-in-here"
})
.getOne();
Where user
is many-to-many
with teams
, and team
is many-to-many
with messages
, I get empty arrays if there is no relationship.
Either:
{
"id": "UUID-in-here",
"teams": []
}
or:
{
"id": "UUID-in-here",
"teams": [
"id": "UUID-in-here",
"messages": []
]
}
How do I setup the relationship/query to avoid having that object with nulled properties when there are no results?
Issue Analytics
- State:
- Created 4 years ago
- Reactions:5
- Comments:11 (3 by maintainers)
I stumbled across the same problem yesterday. It has something to do with the composed primary key over two relations (over event and user in the example above). If there is a separate primary id column instead, the result does not contain the object with null properties.
Omg, this issue is from before COVID era. Any milestone?