typeorm: EventSubscriber not getting updated values for update using queryBuilder and manager.update methods.
Issue type:
[x] question [ ] bug report [ ] feature request [ ] documentation issue
Database system/driver:
[ ] cordova
[ ] mongodb
[ ] mssql
[ ] mysql / mariadb
[ ] oracle
[x] postgres
[ ] sqlite
[ ] sqljs
[ ] react-native
TypeORM version:
[ ] latest
[ ] @next
[ ] 0.x.x (or put your version here)
Steps to reproduce or a small repository showing the problem: Whenever entity is update using queryBuilder update method or entity update method, the EventSubscriber’s afterUpdate method gets triggered, but the UpdateEvents entity, databaseEntity, updatedColumns, updateRelations are always empty. These fields are populated only when the updates are done using save methods. Is this intended behaviour.
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 8
- Comments: 22 (5 by maintainers)
Commits related to this issue
- adds test for #2246 — committed to CanKattwinkel/typeorm by deleted user 6 years ago
TypeORM is huge and has lot of small functionality and lot of quirks. There are hundred such small details all of them simply can’t be documented not only because its impossible to keep in mind all small facts like this, but also because it will complicate documentation. Maybe I’ll add this to documentation in the future.
wow, wow so many dislikes on my above post ^ Okay, okay, now I definitely know we need to add this to the docs.
maybe the listenerMethod should just be renamed (+ aliased for backwards compatibility) to
afterSaveto avoid this confusion.But then, what’s the preferred approach to reliably act upon update of an entity, with data about the entity itself available? By reliably, I mean no matter of the way the data is updated, whether is
.save()or.update(), or query builder or whatever.I don’t want to be forced to remember to use certain way of updating just because somewhere on the other end of the repository there’s a subscriber that reacts differently to different methods.
TypeORM gives you lots of control over your database interactions. You can use high-level, fully-featured but less efficient operations, or low-level and fast operations.
EntityManager.save), TypeORM has full access to the entity and can do additional queries to determine whether inserting or updating. Therefore TypeORM can call subscribers with entities.EntityManager.insert,EntityManager.update,EntityManager.delete), TypeORM does not always have access to entities, but does know the operation. Therefore TypeORM can call subscribers, but cannot always provide the entities.QueryRunner.query), TypeORM does not know what you’re doing and doesn’t have access to entities or subscribers.Each method has tradeoffs. You have to decide the best fit for your use case.
If you want to see exactly what the orm is doing, turn on logging and check out the SQL being executed for your operations
@NickKelly1 you can call the save method instead of the update method
Thanks for your patience, I get it now.
Since this is not quite obvious, should it be mentioned in the docs?
https://github.com/typeorm/typeorm/blob/master/docs/listeners-and-subscribers.md#beforeupdate
@pleerock then it works - is this the desired behavior? Because this feels confusing.
Listeners are confusing but because of flexibility and functionality orm provides. With
saveyou can always have an entity or partial entity which you insert/update. Withupdateandupdate query builderyou have more like a set of values to be used in UPDATE query. For example:counterin entity is actually a number, but this is a valid syntax forupdate, and if we pass this update set to listener we can’t call itentityanymore.