I just played around a bit and wanted to share my findings. Essentially, what Hibernate does is to keep the reference equality by not replacing the already known proxy with the real instance. The problem obviously is that the proxy is not of the right subtype, but narrowing the proxy like you do in your PR breaks reference equality, so I'd rather not have that PR approved. Other JPA providers "solve" this issue by always fetching the subtype i.e. do separate queries or add joins for the subtype tables. If enhancement is used, the other JPA providers even defer the loading to the actual access which is desireable. There are two possible solutions to this problem
- Serve declaration typed instances and replace them with concrete subtypes when loaded
- Always use the @Proxy(lazy = false) semantics for polymorphic types i.e. always load such entity instances
Apart from 1. being very complex(also see
HHH-11387 Open ) it still doesn't solve all of the problems. The original instance is still of the wrong type and after loading, it is not managed anymore. Using 2. on the other hand would fix all problems but incur a little overhead because of the additional joins/selects for the subtypes. When using bytecode enhancement, the loading of *ToOne instances could be deferred to the first access. Actually it would also be possible if property access is used without bytecode enhancement, but that would require to use a special proxy for every object that might contain a non-initialized polymorphic association that loads the association on first access. |