Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: Tip: how to generate multi-field finders

  1. #1
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    667

    Lightbulb Tip: how to generate multi-field finders

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

    Code:
    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:

    Code:
    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:

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

    Code:
    findCarsByColour(Colour colour)
    findCarsByKilometres(Integer kilometres)
    findCarsByKilometresBetween(Integer minKilometres, Integer maxKilometres)
    findCarsByKilometresEquals(Integer kilometres)
    findCarsByKilometresGreaterThan(Integer kilometres)
    findCarsByKilometresGreaterThanEquals(Integer kilometres)
    findCarsByKilometresIsNotNull()
    findCarsByKilometresIsNull()
    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)
    findCarsByPurchaseDateIsNotNull()
    findCarsByPurchaseDateIsNull()
    findCarsByPurchaseDateLessThan(Date purchaseDate)
    findCarsByPurchaseDateLessThanEquals(Date purchaseDate)
    findCarsByPurchaseDateNotEquals(Date purchaseDate)
    findCarsByVIN(String VIN)
    findCarsByVINEquals(String VIN)
    findCarsByVINIsNotNull()
    findCarsByVINIsNull()
    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:

    Code:
    findCarsByColourAndKilometresBetweenAndMakeAndModelAndPurchaseDateBetweenAndVINLikeAndWarranty
    Open your Car.java file, and change this line:

    Code:
    @RooEntity
    To include the above finder name:

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

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

    Code:
    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 Car.java 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 at 09:19 PM. Reason: Spotted a missing parenthesis 18 months later!
    Andrew Swan
    "Now is the EJB of our discontent made glorious Spring"

  2. #2
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    667

    Post The domain script

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

    Code:
    project --topLevelPackage com.example.car
    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
    Andrew Swan
    "Now is the EJB of our discontent made glorious Spring"

  3. #3
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    667

    Post 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.
    Andrew Swan
    "Now is the EJB of our discontent made glorious Spring"

  4. #4

    Default

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

  5. #5
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    667

    Thumbs down 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 at 12:11 AM.
    Andrew Swan
    "Now is the EJB of our discontent made glorious Spring"

  6. #6
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    The best present information on how to develop an add-on can be found in my http://www.slideshare.net/benalexau/...ical-deep-dive presentation. You might also wish to vote for or watch the http://jira.springframework.org/browse/ROO-631 issue.
    Ben Alex
    Project Founder, Spring UAA, Spring Roo and Spring Security

  7. #7
    Join Date
    Jan 2010
    Location
    Lanus, Argentina
    Posts
    28

    Default

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

    Thanks Andrew!!!!

    PD:
    of course it helps!!!!

  8. #8

    Default

    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. #9
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    667

    Default

    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.
    Andrew Swan
    "Now is the EJB of our discontent made glorious Spring"

  10. #10

    Default

    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.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •