Open yrodiere opened 9 hours ago
/cc @gsmet (hibernate-orm)
We advise people to use DTOs not just for this good reason (transaction being closed between endpoint and serialisation) but also for other good reasons:
merge
parameters blindly) that should not be exposedSo that's already three good reasons to not waste time helping people send entities over REST outside of pet/demo projects. I'm frankly not sure we should spend time and effort in that direction.
Now, if you absolutely must serialise entities to JSON, assuming you have a pet/demo project that does not care about security and has no relations, perhaps we could talk about entity graphs instead? so that the right data is already loaded efficiently and there's no need to extend the transaction?
https://docs.jboss.org/hibernate/orm/6.6/userguide/html_single/Hibernate_User_Guide.html#fetching-strategies-dynamic-fetching-entity-graph but also fetch queries are options.
That's very good arguments, and I'd certainly welcome a world where nobody serializes entities (even with entity graphs, TBH).
And yet... people do serialize entities. Worse, I suspect people enable lazy loading outside of transactions -- or at least try to.
My goal here was to make sure that people do as little dangerous stuff as possible, and evidently offering DTOs as a solution isn't enough since I rarely see it mentioned. Possibly because it's seen as inconvenient, but perhaps also because people have less issues when they use DTOs... survivor bias?
Maybe I'm not being realistic as we need to prioritize our effort indeed. But if we're not going to work on this, maybe let's be clear about it. Should we just document serializing entities -- especially with lazy loading -- as an unsupported bad practice, agree we'll reject all related issues, and call it a day?
Description
Some people have their Rest endpoints return entities, or
List<MyEntity>
, or types that have nested entities. That is dangerous as serialization currently happens after the transaction ends, even if@Transactional
is applied to the endpoint method, so at best lazy-loading will fail, at worst it will rely on a query that runs outside of the original transaction and thus might return inconsistent data.However, if we could make sure that serialization happens within the transaction, while making sure that the transaction ends before quarkus-rest/RestEasy handles exceptions (in case the serialization/transaction fails), then this practice would become safer as far as consistency is concerned -- though serializing a lazy-loadable entity always comes with the risk of serializing the whole database, but that's what
@JsonIgnore
and friends are for 🤷Extracted from https://github.com/quarkusio/quarkus/issues/30096#issuecomment-2516659142 :
Implementation ideas