Skip to Content.
Sympa Menu

grouper-dev - Re: [grouper-dev] Manage Groups

Subject: Grouper Developers Forum

List archive

Re: [grouper-dev] Manage Groups


Chronological Thread 
  • From: Chris Hyzer <>
  • Cc:
  • Subject: Re: [grouper-dev] Manage Groups
  • Date: Wed, 11 Jul 2007 09:36:50 -0400

Here are two framework methods we use (on hibernate projects, but not on grouper) to get one-to-manies in one query instead of hundreds (unmapped relationship in hibernate) (some method calls are other framework methods, let me know if you want that code too)... of course if you have a tree structure (instead of list), you will have to accommodate that, the easiest way might be to flatten the tree into a list, and call a method like this, and you will still have the tree structure intact:

/**
* for a list of objects with unmapped one-to-many relationship, get the
* manies in one query and assign back to the one
* @param <T>
* @param objects
* @param fieldNameManyForeignKey
* @param manyClass
* @param criterion additional hibernate criteria to attach to the one-to-many relationship,
* or null if you want all
* @return Map
*/
@SuppressWarnings("unchecked")
public static <T> Map<Object, List<T>> retrieveOneToManies(List<?> objects,
String fieldNameManyForeignKey, Class<T> manyClass,
Criterion criterion) {

Map<Object, List<T>> theObjects = new HashMap<Object, List<T>>();
int length = FastObjectUtils.length(objects);

if (length == 0) {
return theObjects;
}

List<Serializable> ids = new ArrayList<Serializable>();

//Get the list of foreign key values.
for (int i = 0; i < length; i++) {
ids.add((Serializable) FastPropertyUtils.propertyValue(objects.get(i),
fieldNameManyForeignKey));
}

if (ids.size() == 0) {
return theObjects;
}
List<Criterion> expressionList = new ArrayList<Criterion>();

//Create a criteria to retrieve entities for the foreign keys.
expressionList.add(criterion);
expressionList.add(Restrictions.in(fieldNameManyForeignKey, ids.toArray()));

//retrieve the manies
List<T> manies = HibernateSession2.byCriteriaStatic().listSelect(manyClass,
HibUtils.listCrit(expressionList));

//Populate the map.
for (T child : manies) {

//Get the value of the foreignKey attribute.
Object keyVal = FastPropertyUtils.propertyValue(child, fieldNameManyForeignKey);

//Get the list from the map for the foreignKey value if one exists, else return a new list.
List<T> list = theObjects.containsKey(keyVal) ? (List<T>) theObjects.get(keyVal)
: new ArrayList<T>();
//add to the list.
list.add(child);

//Add/replace the value of the key.
theObjects.put(keyVal, list);
}

return theObjects;
}

/**
* get the one to manies for an array of objects, assign them to the
* rigth instance, return the new list of one to manies
* (in case we need to chain)
* @param <T> is the template class type
* @param objects objects to get the one to manies
* object which is the foreign key (on one side). needs to be integer
* @param fieldNameManyForeignKey java field of the many table which is the
* foreign key to the
* one table. * @param manyClass is the class name for the many class
* @param oneFieldForManies field name in the one class which holds an array of the
* manies
* @return the list of objects found to be foreign keys (for further processing)
*/
public static <T> List<T> retrieveOneToManies(List<Object> objects,
String fieldNameManyForeignKey, Class<T> manyClass,
String oneFieldForManies) {
int length = FastObjectUtils.length(objects);
if (length == 0) {
return new ArrayList<T>();
}
List<Serializable> ids = new ArrayList<Serializable>();
String objectIdFieldName = HibUtilsMapping.primaryKeyPropertyName(objects.get(0).getClass());
for (int i=0;i<length;i++) {
ids.add((Serializable)FastPropertyUtils.propertyValue(objects.get(i), objectIdFieldName));
}
//retrieve the manies
List<T> manies = HibernateSession2.byObjectStatic().listSelect(manyClass, ids);
int manySize = FastObjectUtils.length(manies);
//make array of ids to make easy to process
Serializable[] manyIds = new Serializable[manySize];
for (int i=0;i<manySize;i++) {
manyIds[i] = (Integer)FastPropertyUtils.propertyValue(manies.get(i),
fieldNameManyForeignKey);
}
//sync them up
for (int i=0;i<length;i++) {
List<Object> manyList = null;
for (int j=0;j<manySize;j++) {
if (ids.get(i).equals(manyIds[j])) {
if (manyList == null) {
manyList = new ArrayList<Object>();
}
manyList.add(manies.get(j));
}
}
//see if we need to set
if (manyList != null) {
FastPropertyUtils.assignProperty(objects.get(i),oneFieldForManies,manyList);
}
}
return manies;
}


Michael R. Gettes wrote:
I took shilen's CSV to try and get a better look at the stats.
4.3 seconds are spent on the top 3 by time (and count).
I then went ahead and determined avg ms per call and then
grabbed the top 5. 1.5 seconds are spent on these as well.
I suggest investigating select statements on lines
2,3,4,5,8,11 and 12

/mrg




Archive powered by MHonArc 2.6.16.

Top of Page