Announcement Announcement Module
No announcement yet.
Tip: how to generate multi-field finders Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Tip: how to generate multi-field finders

    A real-world domain object can have quite a few fields, for example:

    public class Car {
        private Make make;
        private Model model;
        private String VIN;
        private Colour colour;
        private Date purchaseDate;
        private Warranty warranty;
        private int kilometres;
    Imagine you've been asked to implement a search screen in which the user can search by all seven of these fields at once (not such an unusual requirement). If you try this Roo command:

    finder list --class ~.Car --depth 7
    ... the Roo shell will die with an OutOfMemoryError, quite understandable given that the possible combinations of finders for seven fields is mind-bogglingly huge (there's a PhD thesis for someone).

    The solution is to list the finders at a depth of one, like this:

    finder list --class ~.Car
    ... which will output this:

    findCarsByColour(Colour colour)
    findCarsByKilometres(Integer kilometres)
    findCarsByKilometresBetween(Integer minKilometres, Integer maxKilometres)
    findCarsByKilometresEquals(Integer kilometres)
    findCarsByKilometresGreaterThan(Integer kilometres)
    findCarsByKilometresGreaterThanEquals(Integer kilometres)
    findCarsByKilometresLessThan(Integer kilometres)
    findCarsByKilometresLessThanEquals(Integer kilometres)
    findCarsByKilometresNotEquals(Integer kilometres)
    findCarsByMake(Make make)
    findCarsByModel(Model model)
    findCarsByPurchaseDate(Date purchaseDate)
    findCarsByPurchaseDateBetween(Date minPurchaseDate, Date maxPurchaseDate)
    findCarsByPurchaseDateEquals(Date purchaseDate)
    findCarsByPurchaseDateGreaterThan(Date purchaseDate)
    findCarsByPurchaseDateGreaterThanEquals(Date purchaseDate)
    findCarsByPurchaseDateLessThan(Date purchaseDate)
    findCarsByPurchaseDateLessThanEquals(Date purchaseDate)
    findCarsByPurchaseDateNotEquals(Date purchaseDate)
    findCarsByVIN(String VIN)
    findCarsByVINEquals(String VIN)
    findCarsByVINLike(String VIN)
    findCarsByVINNotEquals(String VIN)
    findCarsByWarranty(Warranty warranty)
    Copy and paste that list into a text editor, then hack it around until you get a valid finder name that matches your business requirements, for example:

    Open your file, and change this line:

    To include the above finder name:

    @RooEntity(finders = {"findCarsByColourAndKilometresBetweenAndMakeAndModelAndPurchaseDateBetweenAndVINLikeAndWarranty"})
    (Note that until Roo 1.0.2, you need to include the curly braces because of ROO-618.)

    Save the file. Next time you run the Roo shell, it will output this:

    Created SRC_MAIN_JAVA\com\example\car\Car_Roo_Finder.aj
    Open that AspectJ ITD and you will see your new finder in all its glory. If you want to modify it, you can push it into as with any other introduced method.

    If the finder name you came up with is invalid, Roo will tell you there's no such finder available, in which case fix the name and try again.

    Hope this helps someone...
    Last edited by Andrew Swan; Sep 28th, 2011, 09:19 PM. Reason: Spotted a missing parenthesis 18 months later!

  • #2
    The domain script

    Here's the script for the above project in case you want to replicate this for yourself:

    project --topLevelPackage
    persistence setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY 
    entity --class ~.Make
    entity --class ~.Model
    entity --class ~.Warranty
    entity --class ~.Colour
    entity --class ~.Car
    field reference --fieldName make --type ~.Make
    field reference --fieldName model --type ~.Model
    field reference --fieldName colour --type ~.Colour
    field reference --fieldName warranty --type ~.Warranty
    field date --fieldName purchaseDate --type java.util.Date
    field string --fieldName VIN 
    field number --fieldName kilometres --type java.lang.Integer --primitive


    • #3
      Web, too

      The other thing I forgot to mention is that Roo will also generate the controller methods and the view for that finder, which gives you a great starting point for creating a customised search screen.


      • #4
        Thanks Andrews, we are learning to use roo at the moment. Point us to addon internals/ howto create addon using STS.


        • #5
          Off topic

          Unfortunately I've never written an addon and can't help you. Try searching this forum and/or the reference docs. Also, please stay on-topic; this thread isn't about addons.
          Last edited by Andrew Swan; Feb 17th, 2010, 12:11 AM.


          • #6
            The best present information on how to develop an add-on can be found in my presentation. You might also wish to vote for or watch the issue.


            • #7
              Spectacular!!!!!!!!!!!!!!!!!! (As we would say in Argentina)
              that's a really great hack!!!!!

              Thanks Andrew!!!!

              of course it helps!!!!


              • #8
                Thank you very much for posting this finder tip. Very useful!

                Suppose I have two other Entities with relationships to my Car:

                Dealership which has one or more Cars
                Car has one or more instances of Carpart

                Suppose further that I want a query screen which can search for Cars by Dealership Name and Carpart Type. Any tips?


                • #9
                  Good question. You'd have to look into the internals of the @RooEntity annotation to see how it turns the finder name you provide into an actual finder method, but in any case it's unlikely that Roo can generate finders across multiple fields of multiple entities as you require. Your best bet is to generate as much of the finder as you can using Roo, then push it in and modify it to include the other fields you want to query.


                  • #10
                    Thank you, andrews. I have a related question on the Show/Create side that I will post to a separate thread, since it's away from the topic of finders.


                    • #11
                      Great! Andrew. You asked me in another thread - which documentation is priority? I would say what PaoloValladolid asked is a valid question and it would be great if we have documentation on how to enable multiple fields finders across one and multiple domain would be a good start.


                      • #12
                        Hi Andrew,

                        I tried multiple field finder in a single domain - as like you mentioned. This forces me to enter all the search fields. So I tried using Or instead of And between method name, still it forces me to enter all search fields.

                        I make required="false" in jspx but still server side is throwing error that fields data is missing (both in case of And and Or)

                        Can u pls let me know a solution for this?



                        • #13
                          I found in aspectJ file Domain_Roo_Finder.aj - the fields are validated for search. How can I edit the file to make the search fields optional. Means only the entered search fields should be part of the SQL query. I also read in a documentation that it is not suggested to modify the aspectJ (I found Roo replacing the modifications in aspectJ).

                          How to generate a customized aspectJ or modify an aspectJ(that should not be replaced by Roo)


                          • #14
                            In STS: select the aspect file (.aj), right click -> refactor -> push in... and a wizard will allow you to select the methods that you want to move to (push in) the java file.

                            Take care to select all the involved methods and attributes (for instance, in a test, maybe you need to choose a method and the DataOnDemand attribute)

                            Press preview to verify and then finish.


                            • #15
                              Originally posted by nprabakaran View Post
                              I found in aspectJ file Domain_Roo_Finder.aj - the fields are validated for search. How can I edit the file to make the search fields optional. Means only the entered search fields should be part of the SQL query.
                              I just noticed that this has already been logged as ROO-2032. Please follow the link and vote for it if you would still like to see it happen.