[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ojb-user
Subject:    RE: Need help to auto-retrieve some individuals
From:       edson.richter () mgrinformatica ! com ! br
Date:       2004-04-28 19:42:43
Message-ID: 37316.200.213.48.4.1083181363.squirrel () webmail ! plugin ! com ! br
[Download RAW message or body]

I have some "father" with large number of "childs" in some of our project. The solution I've
found is make the getChildren() method execute a PB Query (of course you can use other apis)
using

...
Criteria c = new Criteria();
c.addEqualTo("fahter.id", fatherId); //this tells to what father we are looking for
c.addEqualTo("childType", childWanted); // you can check sex, age and so on here...
QueryByCriteria q = new QueryByCriteria(Child.class, c);
...


Of course, you will need to change the values according to your app. Not loose performance
if you use DefaultCache. Dont forget to index your child by FATHERID, CHILDTYPE columns (or
other columns - in majority of databases, indexing only by FATHERID is sufficient), so it
can be really fast!!!

I expect this helps,

Edson Richter


> The pattern I typically use for this is to provide accessors for the collection that take a
> filter:
>
> public interface Filter
> {
>     public boolean accept(Object o);
> }
>
>
> public class CollectionUtil
> {
>     public static List filter(List l, Filter f)
>     {
>         ArrayList result = new ArrayList();
>
>         for (int i = 0; i < l.size(); i++)
>         {
>             Object item = l.get(i);
>             if (f.accept(item)) result.add(item);
>         }
>
>         return result;
>     }
> }
>
>
> public class Father
> {
>     private List children;
>
>     public List getChildren()
>     {
>         return children;
>     }
>
>     public List getChildren(filter f)
>     {
>         return CollectionUtil.filter(children, f);
>     }
> }
>
> public class Child
> {
>     private String gender;
>     private int age;
>
>     public String getGender()
>     {
>         return gender;
>     }
>
>     public int getAge()
>     {
>         return age;
>     }
>
>     // I typically then define common filters that I expect to be useful on the class of the
> object
>     // being filtered but the client can define their own for other criteria
>
>     public static final Filter MALES = new Filter()
>         {
>             public boolean accept(Object o)
>             {
>                 return ((Child) o).getGender().equals("male");
>             }
>         };
>
>     public static final Filter FEMALES = new Filter()
>         {
>             public boolean accept(Object o)
>             {
>                 return ((Child) o).getGender().equals("female");
>             }
>         };
>
>     public static final Filter MINORS = new Filter()
>         {
>             public boolean accept(Object o)
>             {
>                 return ((Child) o).getAge() < 18;
>             }
>         };
>
>     public static final Filter ADULTS = new Filter()
>         {
>             public boolean accept(Object o)
>             {
>                 return ((Child) o).getAge() >= 18;
>             }
>         };
> }
>
> So the client code is just something along the lines of:
>
>     List femaleChildren = father.getChildren(Children.FEMALES);
>
> It leaves itself open to defining composite filters and negating filters as well to combine
> conditions, i.e.:
>
>     List femaleAdultChildren = father.getChildren(new CompositeFilter(Children.FEMALES,
> Children.ADULTS));
>
> In this example the assumption is that all of the children are loaded into memory.  As has
> been pointed out this works great if the collection of child objects is reasonable but you
> probably wouldn't want to take this approach if the children were in the 10's of thousands
> and the filter is fairly selective (male/female isn't very selective, you expect whichever
> query you do to return roughly half the collection).  In a couple of situations like that
> I've used the same pattern but had the filter be a little more introspectable and
> implemented the equivalent of getChildren(filter) by introspecting on the filter and
> constructing a query object and doing a query to get the results.
>
> As Armin said there are query customizers as well.  The problem I think you'll have there
> though is if the membership in the collection overlaps as in my male/female - adult/minor
> example above.  The collections are really modeled to represent relationships not arbitrary
> queries.  In this case each child is going to belong to two distinct collections, it's
> unclear to me what happens when you remove a child from the 'females' collection but I'm
> guessing there will be inconsistency with other collections you have currently loaded that
> contain that same child.
>
>
> -----Original Message-----
> From: Armin Waibel [mailto:arminw@apache.org]
> Sent: Tuesday, April 27, 2004 8:52 AM
> To: OJB Users List
> Subject: Re: Need help to auto-retrieve some individuals
>
>
> Hi Gustavo,
>
> did you see the query customizer stuff?
> http://db.apache.org/ojb/tutorial3.html#Customizing%20collection%20queries
>
> regards,
> Armin
>
> gfaerman@fys.com.ar wrote:
>
>> Thanks Edson for your quick answer.
>> We  īve already seen your approach. The problem we see with it,is in our
>> real world, the fact that attributes values are more than two in some
>> cases (male and female is just a set of two for this example), and as you
>> say, in some cases there is a large numbre of childre. We envision our
>> requirement (retrieving a subset of child objects) more as a behaviour
>> pattern than a business method.
>> Let īs say attribute is something like the object state, and values could
>> be active, inactive, suspended, deprecated, preferred etc. and let say as
>> you suggest, there is a very large number of children. There are so many
>> combinations to hard code business methods for each persistent class.
>> OJB capabilities to retrieve collections are great. I would like to see
>> them enhaced to be able to retrieve collection sub sets just passing some
>> "criteria". Arguments might be class collection name, attribute, value and
>> connector (equal, not equal, less than etc.).
>> In the mean time we are thinking about delegating this to a helper class
>> or some storage controller thing in order to avoid coding class by class.
>> We suspect this will not be that efficient in terms of database reads etc.
>> compared to a pure OJB native solution.
>>
>> Thanks!
>> Gustavo.
>>
>>
>> Edson Carlos Ericksson Richter <edson.richter@mgrinformatica.com.br> wrote
>> on 27/04/2004 09:55:28 a.m.:
>>
>>
>>>Unless your Father has a very large number of children (as can occur in
>>>a Construction and the elements of construction in a price building
>>>system), you will find easier to get all childrens and implements two
>>>business methods in your Father bean: getFemaleChildrens() and
>>>getMaleChildrens().
>>>
>>>So, you will have three ways to get the data you want, withou need to
>>>execute more than two selects on database. If you use JavaBeans based
>>>programming, when OJB call setChild, you can separate males and females,
>>
>>
>>>and kee each in theyr own list...
>>>
>>>Just my 2c,
>>>
>>>Edson Richter
>>>
>>>
>>>gfaerman@fys.com.ar wrote:
>>>
>>>
>>>>Hi all,
>>>>
>>>>Let's say we have an object name Father, who has a Child class
>>
>> collection
>>
>>>>(aggregate association). With the right repository settings
>>
>> (autoretrieve=
>>
>>>>true etc.) every time we "load" a father from the database, the
>>
>> children
>>
>>>>will be instantiated (they may be proxies or materialized).
>>>>
>>>>Here's our ignorance: when we retrieve a father we need the retrieved
>>>>children collection, to be just a subset of the all father's children
>>>>collection. The children are those with a any given attribute set to a
>>
>> any
>>
>>>>given value (let say just those children with gender attribute set to
>>>>female).
>>>>
>>>>This is just like having a filter or criteria setting at the owned
>>>>collection level.
>>>>Please pay attention to the fact we do not want to filter the fathers
>>>>based in some children attributes. We need retrieve all fathers, just
>>>>filtering some children.
>>>>
>>>>We are aware we could retrieve the father an then iterate the
>>
>> collection
>>
>>>>discarding the children we do not need, but we need this to become a
>>>>common feature for our classes, not just a business logic for a single
>>>>app, therefore we would like to know how to handle this in general.
>>>>
>>>>
>>>>Thanks in advance,
>>>>Gustavo Faerman.
>>>>
>>>>Buenos Aires, Argentina
>>>>
>>>>
>>>
>>>
>>>---------------------------------------------------------------------
>>>To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
>>>For additional commands, e-mail: ojb-user-help@db.apache.org
>>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-user-help@db.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-user-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-user-help@db.apache.org

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic