I have an update on this thread, sorry for the delay. Upon a much deeper dive into the write side of this issue, there have been found a number of contributing factors that was causing an unnecessarily long end user wait time upon save/write. Most of these have nothing to do with GWT, RequestFactory, or Hibernate. While we have addressed those issues a bit, one part does standout as a pattern for this type of situation when using RequestFactory.
The part that did help reduce response time was to eagerly load the extents of this noted graph in the ServiceLocator for the A class. Such that when the A graph is returned from the find() method in AServiceLocator, all of the relationships in the graph have been fully initialized and hydrated. All of those OneToMany relationships are housed in java.util.ArrayList typed instance variables in our case, and Hibernate won't let you eagerly load more than one of those typed relationships in one query (shaking my fist at you Hibernate!), so instead we just wrote code to walk the graph once the A instance had hydrated via EntityManager, and that resulted in a significant reduction in database i/o to hydrate the full extents of the A graph. While the "Eagerly load aggregate graph in aggregate ServiceLocator on write" trick did help quite a bit, it was just a portion of all of the optimizing we needed to put in place to get the system response time for the write use case ratcheted down to more acceptable levels. Thanks for the help. Doug On Thursday, November 7, 2013 12:53:48 AM UTC-8, Thomas Broyer wrote: > > Anyone volunteers to profile the code to have hints about what's slow? > > IMO, one solution could be to switch to code generation rather than > reflection (particularly the AutoBeans), but that's only if reflection is > the bottleneck. > > On Thursday, November 7, 2013 8:50:08 AM UTC+1, Ümit Seren wrote: >> >> Well that's weird. you could put a breakpoint in the getter for the >> sub-references and see if it gets called when you save without with(). >> >> >> On Wed, Nov 6, 2013 at 10:22 PM, Doug Gschwind <[email protected]>wrote: >> >>> Hi Umit, >>> >>> Oh, I like the idea of the wildcarding in those String instances passed >>> to with(), would help with refactoring efforts if properties change or are >>> moved to other classes in a graph. >>> >>> According to my testing though, I see no difference in results if upon >>> save we do, or do not use, a valid call to with(args). Given that, I will >>> likely abandon any tweaks in that area. >>> >>> Thanks, >>> >>> Doug >>> >>> >>> On Wednesday, November 6, 2013 12:08:08 AM UTC-8, Ümit Seren wrote: >>> >>>> The reason why you have to specify the references in `with()` is >>>> exactly that sometimey you don't need the entire domain graph on the >>>> client. This way you can specify what you really want to have sent over >>>> the >>>> wire, potentially saving bandwith and improve de-serialization speed. >>>> >>>> There is an issue in the issue tracker (can't find it tough) to support >>>> wildcards a la `with('A.*')` or 'with(A.**)`, if you really need to load >>>> the entire graph. But I am not sure if that is already implemented >>>> >>>> >>>> On Tue, Nov 5, 2013 at 9:42 PM, Doug Gschwind <[email protected]>wrote: >>>> >>>>> Hi Umit, >>>>> >>>>> Thanks for those thoughts. I failed to mention our use of with() in >>>>> this area. When we read the graph from the server, we do in fact make use >>>>> of with() with an extensive list of Strings to force the EntityProxy >>>>> graph >>>>> population as we need. >>>>> >>>>> Interestingly, when we make the call back to the server from client >>>>> code to persist end user edits, we do NOT use with(). I can experiment >>>>> with >>>>> that to see if providing a reduced list of Strings with with() provides >>>>> any >>>>> relief. That is an interesting thought. I personally dislike the fact >>>>> that >>>>> I have to specify with() at all, when my EntityProxy declarations already >>>>> indicate which properties I expect to be in existence on the client side. >>>>> With our graph being so deep, a Domain Model refactoring causes an >>>>> undesirable ripple through those Strings. Providing another list of >>>>> Strings >>>>> for the write based path would add to my discomfort. However, I will do >>>>> some experimenting to see if that can provide any relief. >>>>> >>>>> Thanks, >>>>> >>>>> Doug >>>>> >>>>> >>>>> On Monday, November 4, 2013 11:50:46 PM UTC-8, Ümit Seren wrote: >>>>> >>>>>> @Doug: Sorry I missed the part in your first post where you >>>>>> mentioned that you already return true in the isLive method. >>>>>> >>>>>> RequestFactory uses reflection on the server-side which might be an >>>>>> issue with a huge graph (although I believe it uses caches to speed up >>>>>> things in subsequent calls. >>>>>> I guess you pass the entire graph in the with() call when you >>>>>> retrieve the instance A. >>>>>> If you don’t need to change anything in the sub-nodes (B,C,Ex) you >>>>>> could leave out the with() call for the write action. >>>>>> Or alternatively you could create additional EntityProxys that >>>>>> contain only a subset of the sub-nodes. >>>>>> >>>>>> >>>>>> On Tue, Nov 5, 2013 at 3:13 AM, Doug Gschwind <[email protected]>wrote: >>>>>> >>>>>>> Thanks Umit. Indeed we do that too. We have a ServiceLocator >>>>>>> supertype which all of our concrete ServiceLocator concrete subclasses >>>>>>> extend, and isLive() is implemented to unconditionally return true in >>>>>>> that >>>>>>> implementation. >>>>>>> >>>>>>> Thanks, >>>>>>> >>>>>>> Doug >>>>>>> >>>>>>> >>>>>>> On Monday, November 4, 2013 1:31:28 AM UTC-8, Ümit Seren wrote: >>>>>>>> >>>>>>>> If you don’t care about EntityChangeEvents you can also override >>>>>>>> the isLive() method and return true (see >>>>>>>> here<http://stackoverflow.com/questions/9476341/requestfactory-theory-why-is-locator-find-being-called-so-often> >>>>>>>> ). >>>>>>>> This improved performance quite a bit at least in my case. >>>>>>>> >>>>>>>> On Friday, November 1, 2013 1:20:14 AM UTC+1, Doug Gschwind wrote: >>>>>>>> >>>>>>>> Hello everyone, >>>>>>>>> >>>>>>>>> We are using GWT 2.5.1, Hibernate 4.x as a JPA 2.x provider, >>>>>>>>> Oracle database 11g, and RequestFactory for our application. One of >>>>>>>>> the >>>>>>>>> areas of our application is slightly slow at read time and is >>>>>>>>> noticeably >>>>>>>>> slower at write time. The use case in particular is a fairly complex >>>>>>>>> editor >>>>>>>>> where the read part of the puzzle is used to render the complex UI >>>>>>>>> and the >>>>>>>>> write part of the puzzle is used to save end user edits made in this >>>>>>>>> complex editor UI. In this particular use case, we use >>>>>>>>> RequestFactory. In >>>>>>>>> other areas of our application we have some GWT-RPC in use, but we >>>>>>>>> are >>>>>>>>> migrating away from its use in favor of using RequestFactory. >>>>>>>>> >>>>>>>>> In our RequestFactory use, we use the ServiceLocator pattern and >>>>>>>>> our ServiceLocator's unconditionally return true from isLive(), for >>>>>>>>> background information. We are not using the Editor framework in this >>>>>>>>> area >>>>>>>>> of the application. >>>>>>>>> >>>>>>>>> We have been working on this set of use cases some time and are >>>>>>>>> quite comfortable with the Domain Model that we have in place, which >>>>>>>>> to >>>>>>>>> simplify looks like the following : >>>>>>>>> >>>>>>>>> class A >>>>>>>>> | >>>>>>>>> -- class B >>>>>>>>> | >>>>>>>>> -- class C >>>>>>>>> | >>>>>>>>> -- class D >>>>>>>>> | >>>>>>>>> -- class E >>>>>>>>> | >>>>>>>>> -- class E1 >>>>>>>>> | >>>>>>>>> -- class E2 >>>>>>>>> | >>>>>>>>> -- class E3 >>>>>>>>> >>>>>>>>> There are OneToMany relationships between the following classes : >>>>>>>>> A -> B, B -> C, C-> D, D-> E, E -> E1, E -> E2, E -> E3, with back >>>>>>>>> pointing >>>>>>>>> ManyToOne relationships throughout. Each of these classes are not >>>>>>>>> transportable, in the RequestFactory sense, so we have an EntityProxy >>>>>>>>> for >>>>>>>>> each class. >>>>>>>>> >>>>>>>>> When an end user saves their edits, lots of db query traffic can >>>>>>>>> be seen, which appears to be due to hydrating the entire graph of >>>>>>>>> objects >>>>>>>>> and stitching them together. I suspect that we could reduce the >>>>>>>>> system >>>>>>>>> response time of the save/write use case if all of this >>>>>>>>> ServiceLocator >>>>>>>>> find() infrastructure was subverted since once we read/find the A >>>>>>>>> instance, >>>>>>>>> it can be used to apply all edits without a find() call per node in >>>>>>>>> the >>>>>>>>> graph. >>>>>>>>> >>>>>>>>> Have any of you faced this type of problem and were you able to >>>>>>>>> find an implementation alternative which proved faster by using maybe >>>>>>>>> GWT-JSON or GWT-RPC or some other means? >>>>>>>>> >>>>>>>>> If you got here, thanks for reading and your replies in advance. >>>>>>>>> >>>>>>>>> Doug >>>>>>>>> >>>>>>>>> >>>>>>>> -- >>>>>>> You received this message because you are subscribed to a topic in >>>>>>> the Google Groups "Google Web Toolkit" group. >>>>>>> To unsubscribe from this topic, visit https://groups.google.com/d/to >>>>>>> pic/google-web-toolkit/6ihnfmnuJy8/unsubscribe. >>>>>>> To unsubscribe from this group and all its topics, send an email to >>>>>>> [email protected]. >>>>>>> To post to this group, send email to [email protected]. >>>>>>> >>>>>>> Visit this group at http://groups.google.com/group >>>>>>> /google-web-toolkit. >>>>>>> For more options, visit https://groups.google.com/groups/opt_out. >>>>>>> >>>>>> >>>>>> -- >>>>> You received this message because you are subscribed to a topic in the >>>>> Google Groups "Google Web Toolkit" group. >>>>> To unsubscribe from this topic, visit https://groups.google.com/d/ >>>>> topic/google-web-toolkit/6ihnfmnuJy8/unsubscribe. >>>>> To unsubscribe from this group and all its topics, send an email to >>>>> [email protected]. >>>>> To post to this group, send email to [email protected]. >>>>> Visit this group at http://groups.google.com/group/google-web-toolkit. >>>>> For more options, visit https://groups.google.com/groups/opt_out. >>>>> >>>> >>>> -- >>> You received this message because you are subscribed to a topic in the >>> Google Groups "Google Web Toolkit" group. >>> To unsubscribe from this topic, visit >>> https://groups.google.com/d/topic/google-web-toolkit/6ihnfmnuJy8/unsubscribe >>> . >>> To unsubscribe from this group and all its topics, send an email to >>> [email protected]. >>> To post to this group, send email to [email protected]. >>> Visit this group at http://groups.google.com/group/google-web-toolkit. >>> For more options, visit https://groups.google.com/groups/opt_out. >>> >> >> -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/google-web-toolkit. For more options, visit https://groups.google.com/groups/opt_out.
