Related IRC discussion by Emmanuel Bernard and Gunnar Morling:
gmorling so i'm working on leveraging the new EntityExtraState concept for avoiding a second read for embedded assocs 08:07 gmorling basically that works 08:08 gmorling but there is one glitch 08:08 gmorling when using the new IDENTITY strategy for mongodb, the following happens: 08:08 gmorling an "temporary" EE is created in the PC, then insert() is invoked which generates the id and also sets my new ogm extra state 08:09 gmorling then, after that, the EE is overwritten with a new one 08:09 gmorling that loses the ogm extra state attached to the original EE 08:09 gmorling i managed to work-around it by overwriting the DefaultPersistEventListener 08:10 gmorling which memoizes the original EE and then re-sets the ogm extra state to the new EE 08:10 gmorling but it requires an ugly amount of C&P from DefaultPersistEventListener 08:11 gmorling as there are no suitable hooks which could be overridden 08:11 gmorling emmanuel: you got any better ideas? 08:11 emmanuel thinking and looking at the code 08:12 emmanuel gmorling: got a line number for the EE copy in DefaultPersistEventListener 08:13 emmanuel ? 08:13 gmorling sec 08:13 gmorling emmanuel: it happens in AbstractEntityInsertAction#makeEntityManaged() 08:14 gmorling which is invoked through ActionQueue 08:14 gmorling the trigger is addInsertAction() in DefaultPersistEventListener 08:15 gmorling from what i can say, there is no way "to intercept" below the level of DefaultPersistEventListener 08:16 emmanuel gmorling: what does your version look like? (Gist) 08:19 gmorling emmanuel: https://gist.github.com/gunnarmorling/4102d7446e79b036b024 08:20 gmorling it's almost a plain C&P 08:20 gmorling i'm only keeping the original EE on line 37 08:20 gmorling and propagate it ogm extra state (which has been attached in betwen) in line 97 08:21 emmanuel gmorling: I am a bit surprised that the code does not go through EntityIdentityInsertAction.postInsert() -> getSession().getPersistenceContext().replaceDelayedEntityIdentityInsertKeys( delayedEntityKey, generatedId ); 08:31 emmanuel can you check? 08:31 gmorling looking 08:33 gmorling emmanuel: isDelayed is false 08:35 emmanuel gmorling: Ithink the proper fix we should propose ORM is the following 08:36 emmanuel EntityEntryContext.addEntityEntry() 08:36 emmanuel in the if ( alreadyAssociated ) { 08:36 emmanuel you should copy the extra state 08:37 gmorling yes, i thought the same 08:38 emmanuel The only dubious case is, say I delete an entity but the EntityEntry is still present and marked DELETED. And I reattach this deleted entity via persist(). Should the state be copied? 08:39 gmorling hmm 08:39 gmorling wouldnt the new EE in that case have its own extra state already? 08:40 emmanuel gmorling: why? 08:42 emmanuel it would be carried over from DELETE, no? 08:42 gmorling hum, i'm not sure; would have to try it out 08:43 emmanuel the DELETE woudl copy the state, then the identity insert would add a marker EE and replace the DELETED EE then the new EE would be replaced witht he id 08:43 emmanuel but I'm thinking that you can check the EE state 08:43 emmanuel I suppose if you add a break point and you check when the EE is overridden in your case, the marker EE is in SAVING state 08:44 emmanuel right that's most likely SAVING 08:45 emmanuel so in that if alreadyAssociated block, you can check for the state to be SAVING before doing the copy 08:46 gmorling yes, it's SAVING 08:46 gmorling so you'd only copy the extra state if the existing EE is in state SAVING? 08:47 emmanuel gmorling: that's safer as a first step 08:47 gmorling k 08:47 emmanuel also StatefulPersistenceContext.replaceDelayedEntityIdentityInsertKeys should have the copy logic too 08:47 emmanuel here it seems they remove the EE first 08:48 gmorling right 08:48 emmanuel so we can do a two step like last time 08:52 emmanuel your bad hack first 08:52 emmanuel and a proposal for the proper fix in master and 4.x 08:52 emmanuel gmorling: ^ 08:52 gmorling +1 09:02 emmanuel gmorling: thinking a bit more, I think you should not copy the extra state if the previous EE state is DELETED or GONE. And do the copy otherwise 09:15 gmorling sounds reasonable 09:16 gmorling we'd also need a new api on EE for getting "all the extra state" 09:16 gmorling currently one can only ask for a specific one 09:16 emmanuel ah fuck 09:26 emmanuel gmorling: maybe an EntityEntry.copyExtraState(EntityEntry) gmorling 09:29 emmanuel that way you cna keep the nasty chaining sauce hidden without exposing too much 09:29 gmorling yes, that may work 09:30
|