No announcement yet.
  • Filter
  • Time
Clear All
new posts

    Auto-populate bean with criteria map

    Consider the typical bean that i use in my spring fetch/update methods:
    public class ReportRequestTO {
        Date startDate;
        Date endDate;
    In methods where i need to fetch parameters directly off the criteria, i have to have another parameter in the bean method:

    public thing fetch(ReportRequestTO to, Map criteria){
    It would be neat if i instead could have the criteria map auto-populated directly in the bean, i.e. the "Map criteria" would be inside the TO instead. It would be cleaner and remove alot of boilerplate code.

    Is there anyway to get that working?

    Trying to follow this.. so DMI will take the inbound DSRequest and populate a bean if you declare one as a parameter of the method that DMI calls. There is also DataTools.setProperties() if, for whatever reason, auto-population of a parameter doesn't quite work for you, or if you've created a separate bean to represent criteria.

    Is there something more to add, or perhaps you weren't aware of these capabilities?

    Note, of course, here we're talking about simple criteria only. If you use the full SmartClient/SmartGWT server system (SQL/JPA/HB connectors) you get automatic execution of advanced criteria without writing any server code at all, if you are using a SQL DB or really anything that supports JPA. But for the case of connecting to a non-SQL DB or connecting to some other Java layer, obviously we want to make it as simple as possible.


      No i am aware of datatools. I am currently using Apache for those kind of utility methods. What i mean is that by declaring a map in my method, the framework autopopulates it, same as it does with my TO for dataasource fields. I was hoping that you could have auto-population of the criteria map into my TO, so that i won't have to call to.setmap() with the criteria map everywhere. Not a big deal, i am just rewriting old code so thought i'd ask.

      I am aware of the smartgwt server system too (we do have a pro license), it's a great framework.


        Still not following this. You seem to be asking for what the system already does.. if ReportRequestTo is declared as the only parameter, the DMI system will automatically populate it with the inbound values.


          Yes, that's true. However, if you look at the dsrequest, the "requestData" has a map with the datasource values (called 'values'), and another map with the criteria (called 'criteria'. I would have loved to be able to auto-populate the criteria map itself, or the values inside it. I think you only auto-populate the "values" map.

          Right now, i have to have "Map criteria = request.getCriteria();" everywhere, and to do that i also have to have DSRequest as a method parameter every time i need to look at criteria, since i can only get at the criteria through the DSRequest object.
          Last edited by mathias; 19 Dec 2021, 12:47.


            Still quite lost as to how anything can be simplified here..

            It seems like you are hoping for:, specifically in "update" requests (the only ones that have both criteria and values): apply values to a POJO, and provide criteria as a Map?

            But except for the (usually rare) case of allowMultiUpdate, the criteria is just the PK, which means you would already have it in your POJO, read to save to any ORM system. So why would it be important to have it as a separate Map?

            But, even stranger, what would be the point of specifically having a "Map criteria" parameter when you can just declare a DSRequest parameter? If there is some action you need to take on the criteria, either type of parameter should work for whatever helper method you need to call?


              I have a *bunch* of reports. In those screens, there's typically a grid or similar in the bottom and various controls above it where the user can select parameters like start- enddate for the data in the simplest case, or various other parameters related, or not related, to the actual datasource for the report.

              When the user presses "fetch", a fetch-dsrequest is created in the client, with the parameters the user has selected in the form as criteria. On the server, i then have to get the dsrequest out, and do .getCriteria() to get the parameters of the report out. I then run the report and return the data back in the response, which is then populated in the report grid clientside.

              Since the parameters i need is in the criteria and not the datasource-related values (specified in the datasource xml), nor do they belong there, they are in the criteria map and not the values map.

              It would be easier and cleaner to not having to have the smartgwt-specific class DSRequest as a method parameter, and also if i could just declare the criteria map, or have it or its parameters autopopulated somehow, that's all.


                OK, so it's a fetch.. it's not clear why, for a fetch, there is also a POJO in the signature? But again the system already does what you want: for a fetch, a Map as a parameter is populated by the criteria.


                  There's not a pojo for the fetch requests, it seems to be me just being unclear. I was trying to illustrate what i was after, in general, and apparently did a bad job. :). OK, so i'll use the map directly for fetches, great stuff. I must have missed that somehow, i thought the map called "values" contained record values and the map called "criteria" contained the criteria. You live and you learn. :)

                  This brings me update/delete request too though - it's unfortunate that i cannot set criteria for update/delete methods (if i do, it is ignored as specified in the javadoc). I sometimes have to pass additional parameters along with update/delete requests, information not directly related to the record under operation.

                  According to the docs, I have had to use various operation ID shenanigans(which is what i'm doing right now), or use "oldValues" (which i've never tried), but those those approaches make me have the DSRequest as a method parameter, which i'm trying to avoid. Is there some other way to get custom params into the map on delete/update calls?


                    No shenanigans required. Just set "allowMultiUpdate" on the operationBinding, and full criteria are allowed - no longer restricted to require a PK.

                    Just audit such code very carefully - it's honestly not a place to quibble about the convenience of a DSRequest parameter vs Map criteria or whatever - these are rare requests where you should carefully think through everything, because they are wipe the DB requests if you make a mistake!


                      Hey dude(s), (btw thanks for the quick responses!), i agree about rare requests and think through. They won't wipe anything since all my db/sql is "handwritten".

                      Just FYI so you see where i'm coming from. Some examples of where i have parameters not directly related to the datasource under operation:

                      1. When I update/delete a record, there's some instances (such as users) where there are choices about who to notify about the change. "supervisor, HR" etc. This is not related to the datasource, just something that's happening 'on the side'

                      2. i have a scheduling module. a schedule can be recurring, so when you click on a schedule item in a timeline and delete it, the user is given a choice to delete "this item only" "all future" or "everything in the series".

                      So, updates/deletes, since i thought i couldn't use criteria, i've just used set the operationid to an int, and in the update/delete springbean method i've done DSRequest.getOperationId to know what to do.

                      For fetches, an example is a report where the user can select a bunch of lon/lat points to filter data. This needs to happen server-side so a bunch of parameters need to be sent along with the fetch. In these examples as i've mentioned i do request.getcriteria().getthethings()

                      In both instances, the point of this thread was that i'd like to not have smartgwt-custom parameters in my methods (since i have to get stuff out from the request in both examples), but rather more "neutral" things like maps or a popuplated bean somehow.


                        OK, so, still struggling to figure out what you're asking for, but, where we think we are is:

                        1. you didn't know that for a "fetch" operation, you could just declare a Map to get the criteria. So that part is solved.

                        2. for other operations, like "update" or "delete", you needed to pass additional information that wasn't a field of your bean, so you tried to "smuggle" that information in the criteria.

                        Definitely do not try to smuggle extra data as fake "criteria". Putting data into criteria that is not actually criteria will lead to a number of problems, the most obvious of which is that you will break automatic cache synchronization and break in-browser filtering.

                        The best solution for this common use case is to use queuing to create a multiple DSRequest operation. So the notification in your case #1 is just represented as a second DSRequest, part of the same HttpRequest, and then this leads naturally to being able to reuse the notification function in other ways (see QuickStart Guide: search for Queuing, RestHandler, SOAs).

                        From previous posts, we seem to recall that you chose an architecture that broke the queuing feature. Even in this situation, you can still pass additional information in multiple ways that will not also break other features related to criteria:

                        1. pass additional information as an HTTP parameter

                        2. convey the information in the operationId (eg a distinct ID for when everyone is updated vs just some)

                        3. declare an additional DSField for it, but just set it canSave:false and hidden:true so it doesn't appear in the UI

                        So again, just for anyone else reading this: do not try to pass extra information via criteria. Criteria should be actual criteria. Use one of the above options to pass information that is not criteria; the best solution being that recommended in the QuickStart.


                          2. criteria, or operationid which is what we mostly use. The criteria example is as mentioned for fetches for reports, where we cannot use caching at all. But i hear you.

                          Thanks for input. Yeah, the queuing approach is not a great solution for a number of reasons. So it seems that if we want to use "neutral" method parameters, http parameters are actually the best. I don't remember why we didn't use those in the past, but i seem to remember (we've been customers for a long time) that there were issues with setting http parameters in the client, they were sometimes ignored. I could remember wrong.

                          We will looking into moving from operationid to http parameters for our update/delete calls. Thanks!


                            If you can move to queuing, that could be potentially a huge boost to your architecture. Please consider the QuickStart Guide section on queuing and realize that it creates this wonderful ability to reuse every operation that is available on the server, mix-and-match, on the fly, and this capability is literally free - just built in! It also covers things like multiple, mixed updates (like adding a new order and also adding the items to that order). So it's extremely powerful, and simplifies things a lot.

                            But yes, if you have to do something else, HTTP params are probably the second best choice.