db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jakob Braeuchi <jbraeu...@gmx.ch>
Subject Re: [Fwd: Per-criteria pathClass [was ojb-user: Query casts] 1 of 2]
Date Sun, 28 Mar 2004 15:12:54 GMT
hi phil,

now i got your files, thanks.

jakob

Phil Warrick wrote:
> Hi Jakob,
> 
> In case you did not receive these, here they are againDid you not 
> receive these?
> 
> Phil
> 
> -------- Original Message --------
> Subject:     Per-criteria pathClass [was ojb-user: Query casts] 1 of 2
> Date:     Sat, 27 Mar 2004 16:03:47 -0500
> From:     Philip Warrick <Philip.warrick@mcgill.ca>
> To:     undisclosed-recipients <undisclosed-recipients:;>
> 
> 
> 
> Hi Jakob,
> 
> I've done the changes to allow pathClass to be specified per Criteria
> rather than per QueryByCriteria.  The main change from the user point of
> view is the addition of the method Criteria#setPathClass().   So the
> following query is now possible:
> 
> Criteria crit1 = new Criteria();
> crit1.setAlias("alias1");
> crit1.addEqualTo("allBs.c.cAttrib", new String("foo1"));
> crit1.setPathClass("c", C.class); // new: per criteria
> 
> Criteria crit2 = new Criteria();
> crit2.setAlias("alias2");
> crit1.addEqualTo("allBs.c.dAttrib", new String("foo2"));
> crit1.setPathClass("c", C1.class); // new: per criteria
> 
> crit1.addAndCriteria(crit2);
> 
> Query query = new QueryByCriteria(A.class, crit1);
> 
> 
> For backward compatibility, QueryByCriteria#setPathClass() is still
> available.  What happens is that if no pathClass is specified at a
> particular Criteria level, the parent Criteria is searched for a
> pathClass, and so on until the parent Criteria.  If no pathClass is
> found there, the pathClass of the owning QueryByCriteria is accessed.
> I've created a junit test case to test the new functionality; no errors
> have been introduced to the existing broker junit tests with these
> changes (tested with hsqldb).
> 
> I based my changes on the CVS snapshot from 2004/03/14 and notice that
> as of this today, no changes have been made since then to the java
> source that I changed.  I've marked my changes in the code by my
> initials //PAW.  I'd would really like if you could review this code to
> see if there is anything you see that is questionable.
> 
> I'm not proposing that this should be added before 1.0, but I'd like to
> get an iteration out there for feedback before I go ahead with phase II:
>    aliases specified by segment.
> 
> Summary of attached files (sent in 2 messages):
> 
> src files
> o.a.o.b.query.Criteria.java
> o.a.o.b.query.SelectionCriteria.java
> o.a.o.b.query.BetweenCriteria.java
> o.a.o.b.accesslayer.sql.SqlQueryStatement.java
> o.a.o.b.accesslayer.sql.SqlSelectStatement.java
> 
> srcTest files
> ojbTest-schema-pathClass.xml
> repository-junit-pathClass.xml
> o.a.o.b.query.A.java
> o.a.o.b.query.B.java
> o.a.o.b.query.C.java
> o.a.o.b.query.C1.java
> o.a.o.b.query.D.java
> o.a.o.b.query.PathClassTest.java
> 
> test class object model:
> 
> A-1------M-B-1------M-C-1------1-D
>                         |
>                         | (C1 subclass of C)
>                         |
>                         C1
> 
> Thanks,
> 
> Phil
> 
> 
> 
> 
> 
> ------------------------------------------------------------------------
> 
> <!-- ojb test pathClass classes -->
> 	<class-descriptor class="org.apache.ojb.broker.A" table="A_TABLE">
> 	<field-descriptor name="id" column="ID" jdbc-type="BIGINT" primarykey="true" autoincrement="true"/>
> 	<field-descriptor name="aAttrib" column="A_ATTRIB" jdbc-type="INTEGER"/>
>       <collection-descriptor
>          name="bSet"
>          element-class-ref="org.apache.ojb.broker.B"
>          auto-retrieve="true"
>          auto-update="false"
>       >
>       <inverse-foreignkey field-ref="aId"/>
>       </collection-descriptor>
> 	</class-descriptor>
> 
> 	<class-descriptor class="org.apache.ojb.broker.B" table="B_TABLE">
> 	<field-descriptor name="id" column="ID" jdbc-type="BIGINT" primarykey="true" autoincrement="true"/>
> 	<field-descriptor name="bAttrib" column="B_ATTRIB" jdbc-type="INTEGER"/>
> 	<field-descriptor name="aId" column="A_ID" jdbc-type="BIGINT"/>
> 	<reference-descriptor name="a" class-ref="org.apache.ojb.broker.A"><foreignkey field-ref="aId"/></reference-descriptor>
>       <collection-descriptor
>          name="cSet"
>          element-class-ref="org.apache.ojb.broker.C"
>          auto-retrieve="true"
>          auto-update="false"
>       >
>       <inverse-foreignkey field-ref="bId"/>
>       </collection-descriptor>
> 	</class-descriptor>
> 	
> 	<class-descriptor class="org.apache.ojb.broker.C" table="C_TABLE">
> 	<extent-class class-ref="org.apache.ojb.broker.C1" />
> 	<field-descriptor name="id" column="ID" jdbc-type="BIGINT" primarykey="true" autoincrement="true"/>
> 	<field-descriptor name="cAttrib" column="C_ATTRIB" jdbc-type="INTEGER"/>
> 	<field-descriptor name="bId" column="B_ID" jdbc-type="BIGINT"/>
> 	<reference-descriptor name="b" class-ref="org.apache.ojb.broker.B"><foreignkey field-ref="bId"/></reference-descriptor>
> 	<field-descriptor name="dId" column="D_ID" jdbc-type="BIGINT"/>
> 	<reference-descriptor name="d" class-ref="org.apache.ojb.broker.D"><foreignkey field-ref="dId"/></reference-descriptor>
> 	</class-descriptor>
> 	
> 	<class-descriptor class="org.apache.ojb.broker.C1" table="C_TABLE">
> 	<field-descriptor name="id" column="ID" jdbc-type="BIGINT" primarykey="true" autoincrement="true"/>
> 	<field-descriptor name="cAttrib" column="C_ATTRIB" jdbc-type="INTEGER"/>
> 	<field-descriptor name="c1Attrib" column="C1_ATTRIB" jdbc-type="INTEGER"/>
> 	<field-descriptor name="bId" column="B_ID" jdbc-type="BIGINT"/>
> 	<reference-descriptor name="b" class-ref="org.apache.ojb.broker.B"><foreignkey field-ref="bId"/></reference-descriptor>
> 	<field-descriptor name="dId" column="D_ID" jdbc-type="BIGINT"/>
> 	<reference-descriptor name="d" class-ref="org.apache.ojb.broker.D"><foreignkey field-ref="dId"/></reference-descriptor>
> 	</class-descriptor>
> 	
> 	<class-descriptor class="org.apache.ojb.broker.D" table="D_TABLE">
> 	<field-descriptor name="id" column="ID" jdbc-type="BIGINT" primarykey="true" autoincrement="true"/>
> 	<field-descriptor name="dAttrib" column="D_ATTRIB" jdbc-type="INTEGER"/>
> 	</class-descriptor>
> 
> <!-- ojb test pathClass classes -->
> 
> 
> ------------------------------------------------------------------------
> 
> package org.apache.ojb.broker.query;
> 
> import java.util.List;
> import java.util.Map;
> 
> /* Copyright  2004 The Apache Software Foundation
>  *
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
>  * You may obtain a copy of the License at
>  *
>  *     http://www.apache.org/licenses/LICENSE-2.0
>  *
>  * Unless required by applicable law or agreed to in writing, software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  * See the License for the specific language governing permissions and
>  * limitations under the License.
>  */
> 
> /**
>  * abstract baseclass of all criteria classes, can't be instantiated.
>  * 
>  * This code is based on stuff from 
>  * COBRA - Java Object Persistence Layer
>  * Copyright (C) 1997, 1998    DB Harvey-George
>  * eMail: cobra@lowrent.org
> 
>  * @author DB Harvey-George
>  * @author Thomas Mahler
>  * @author <a href="mailto:jbraeuchi@hotmail.com">Jakob Braeuchi</a>
>  * @version $Id: SelectionCriteria.java,v 1.14 2004/03/11 18:16:13 brianm Exp $
>  */
> public abstract class SelectionCriteria implements java.io.Serializable
> {
> 	static final long serialVersionUID = -5194901539702756536L;    protected static final String EQUAL = " = ";
>     protected static final String NOT_EQUAL = " <> ";
>     protected static final String GREATER = " > ";
>     protected static final String NOT_GREATER = " <= ";
>     protected static final String LESS = " < ";
>     protected static final String NOT_LESS = " >= ";
>     protected static final String LIKE = " LIKE ";
>     protected static final String NOT_LIKE = " NOT LIKE ";
>     protected static final String IS_NULL = " IS NULL ";
>     protected static final String NOT_IS_NULL = " IS NOT NULL ";
>     protected static final String BETWEEN = " BETWEEN ";
>     protected static final String NOT_BETWEEN = " NOT BETWEEN ";
>     protected static final String IN = " IN ";
>     protected static final String NOT_IN = " NOT IN ";
> 
> 	private Object m_attribute;
> 	private Object m_value;
> 
> 
> 	// BRJ: true if criterion is bound
> 	private boolean m_bound = false;
> 
> 	// BRJ: the criterion must be bound for the main class and for all extents
> 	private int m_numberOfExtentsToBind = 0; // BRJ: 
> 
> 	private String m_alias = null;
>     
>     // BRJ: indicate whether attribute name should be translated into column name
>     private boolean m_translateAttribute = true;
> 
>     private Criteria m_criteria;
>     
> 	/**
> 	 * Constructor declaration
> 	 *
> 	 * @param anAttribute  column- or fieldName or a Query
> 	 * @param aValue  the value to compare with
> 	 * @param negative  criteria is negated (ie NOT LIKE instead of LIKE)
> 	 * @param alias  use alias to link anAttribute to
> 	 */
> 	SelectionCriteria(Object anAttribute, Object aValue, String alias)
> 	{
>         if (!(anAttribute instanceof String || anAttribute instanceof Query))
>         {
>             throw new IllegalArgumentException("An attribute must be a String or a Query !");
>         }    
>             
> 		m_attribute = anAttribute;
> 		m_value = aValue;
> 		this.m_bound = !isBindable();
> 		this.m_alias = alias;
> 	}
> 
> 	/**
> 	 * Answer the SQL compare-clause for this criteria
> 	 */
> 	abstract public String getClause();
> 
> 	/**
> 	 * sets the value of the criteria to newValue. Used by the ODMG OQLQuery.bind() operation
> 	 */
> 	public void bind(Object newValue)
> 	{
> 		setValue(newValue);
> 		setBound(true);
> 	}
> 
> 	/**
> 	 * Answer the value
> 	 */
> 	public Object getValue()
> 	{
> 		return m_value;
> 	}
> 
> 	/**
> 	 * Answer the attribute
> 	 */
> 	public Object getAttribute()
> 	{
> 		return m_attribute;
> 	}
> 
> 	/**
> 	 * String representation
> 	 */
> 	public String toString()
> 	{
> 		return m_attribute + getClause() + m_value;
> 	}
> 
> 	/**
> 	 * BRJ : Used by the ODMG OQLQuery.bind() operation
> 	 * @return Returns a boolean indicator
> 	 */
> 	public boolean isBound()
> 	{
> 		return m_bound;
> 	}
> 
> 	/**
> 	 * Sets the bound.
> 	 * @param bound The bound to set
> 	 */
> 	protected void setBound(boolean bound)
> 	{
> 		this.m_bound = bound;
> 	}
> 
> 	/**
> 	 * Sets the value.
> 	 * @param value The value to set
> 	 */
> 	protected void setValue(Object value)
> 	{
> 		this.m_value = value;
> 	}
> 
> 	/**
> 	 * answer true if the selection criteria is bindable 
> 	 * BRJ: value null is bindable
> 	 */
> 	protected boolean isBindable()
> 	{
> 		return (getValue() == null);
> 	}
> 	/**
> 	 * Returns the numberOfExtentsToBind.
> 	 * @return int
> 	 */
> 	public int getNumberOfExtentsToBind()
> 	{
> 		return m_numberOfExtentsToBind;
> 	}
> 
> 	/**
> 	 * Sets the numberOfExtentsToBind.
> 	 * @param numberOfExtentsToBind The numberOfExtentsToBind to set
> 	 */
> 	public void setNumberOfExtentsToBind(int numberOfExtentsToBind)
> 	{
> 		this.m_numberOfExtentsToBind = numberOfExtentsToBind;
> 	}
> 
> 	/**
> 	 * @return String
> 	 */
> 	public String getAlias()
> 	{
> 		return m_alias;
> 	}
> 
> 	/**
> 	 * Sets the alias. 
> 	 * @param alias The alias to set
> 	 */
> 	public void setAlias(String alias)
> 	{
> 		m_alias = alias;
> 	}
> 
> 	/**
> 	 * @return true if attribute name should be translated into column name
> 	 */
> 	public boolean isTranslateAttribute()
> 	{
> 		return m_translateAttribute;
> 	}
> 
> 	/**
> 	 * @param b
> 	 */
> 	void setTranslateAttribute(boolean b)
> 	{
> 		m_translateAttribute = b;
> 	}
> 
> 	/**
> 	 * @return
> 	 */
> 	public Criteria getCriteria()
> 	{
> 		return m_criteria;
> 	}
> 
> 	/**
> 	 * @param criteria
> 	 */
> 	void setCriteria(Criteria criteria)
> 	{
> 		m_criteria = criteria;
> 	}
> 
>     public QueryByCriteria getQuery()
>     {
>         if (getCriteria() != null)
>         {
>             return getCriteria().getQuery();
>         }
>         else
>         {
>             return null;
>         }
>     }
>     
> 	/**
> 	 * Gets the pathClasses from the parent Criteria.
> 	 * A Map containing hints about what Class to be used for what path segment
> 	 * @return Returns a Map
> 	 */
> 	// PAW
> 	public Map getPathClasses()
> 	{
> 		return getCriteria().getPathClasses();
> 	}
> 
> 	/**
> 	 * Get the a List of Class objects used as hints for a path
> 	 *
> 	 * @param aPath the path segment ie: allArticlesInGroup
> 	 * @return a List o Class objects to be used in SqlStatment
> 	 * @see #addPathClass
> 	 * @see org.apache.ojb.broker.QueryTest#testInversePathExpression()
> 	 */
> 	public List getClassesForPath(String aPath)
> 	{
> 		return getCriteria().getClassesForPath(aPath);
> 	}
>     
> 
> }
> 
> 
> ------------------------------------------------------------------------
> 
> package org.apache.ojb.broker.accesslayer.sql;
> 
> /* Copyright  2004 The Apache Software Foundation
>  *
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
>  * You may obtain a copy of the License at
>  *
>  *     http://www.apache.org/licenses/LICENSE-2.0
>  *
>  * Unless required by applicable law or agreed to in writing, software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  * See the License for the specific language governing permissions and
>  * limitations under the License.
>  */
> 
> import java.util.ArrayList;
> import java.util.Iterator;
> import java.util.List;
> import java.util.Map;
> 
> import org.apache.ojb.broker.metadata.ClassDescriptor;
> import org.apache.ojb.broker.metadata.FieldDescriptor;
> import org.apache.ojb.broker.query.Criteria;
> import org.apache.ojb.broker.query.Query;
> import org.apache.ojb.broker.query.ReportQuery;
> import org.apache.ojb.broker.util.logging.Logger;
> import org.apache.ojb.broker.platforms.Platform;
> 
> /**
>  * Model a SELECT Statement
>  *
>  * @author <a href="mailto:jbraeuchi@hotmail.com">Jakob Braeuchi</a>
>  * @version $Id: SqlSelectStatement.java,v 1.20 2004/03/12 20:31:54 brj Exp $
>  */
> public class SqlSelectStatement extends SqlQueryStatement
> {
> 
>     /**
>      * Constructor for SqlSelectStatement.
>      * 
>      * @param pf
>      * @param cld
>      * @param query
>      * @param logger
>      */
>     public SqlSelectStatement(Platform pf, ClassDescriptor cld, Query query, Logger logger)
>     {
>         super(pf, cld, query, logger);
>     }
> 
>     /**
>      * Constructor for SqlSelectStatement.
>      *
>      * @param parent
>      * @param pf
>      * @param cld
>      * @param query
>      * @param logger
>      */
>     public SqlSelectStatement(SqlQueryStatement parent, Platform pf, ClassDescriptor cld, Query query, Logger logger)
>     {
>         super(parent, pf, cld, query, logger);
>     }
> 
>     /**
>      * Appends to the statement a comma separated list of column names.
>      *
>      * MBAIRD: if the object being queried on has multiple classes mapped to the table,
>      * then we will get all the fields that are a unique set across all those classes so if we need to
>      * we can materialize an extent
>      *
>      * DO NOT use this if order of columns is important. The row readers build reflectively and look up
>      * column names to find values, so this is safe. In the case of update, you CANNOT use this as the
>      * order of columns is important.
>      *
>      * @return list of column names for the set of all unique columns for multiple classes mapped to the
>      * same table.
>      */
>     protected List appendListOfColumnsForSelect(ClassDescriptor cld, StringBuffer buf)
>     {
>         FieldDescriptor[] fieldDescriptors = cld.getRepository().getFieldDescriptorsForMultiMappedTable(cld);
>         int fieldDescriptorLength = fieldDescriptors.length;
>         ArrayList columnList = new ArrayList();
>         int i = 0;
> 
>         if (fieldDescriptors != null)
>         {
>             FieldDescriptor field = null;
>             for (int j = 0; j < fieldDescriptorLength; j++)
>             {
>                 field = fieldDescriptors[j];
>                 if (i > 0)
>                 {
>                     buf.append(",");
>                 }
>                 buf.append(getSearchTable().alias);
>                 buf.append(".");
>                 buf.append(field.getColumnName());
>                 columnList.add(field.getAttributeName());
>                 i++;
>             }
>         }
>         return columnList;
>     }
> 
>     /**
>      * Appends to the statement a comma separated list of column names.
>      *
>      * @param columns defines the columns to be selected (for reports)
>      * @return list of column names
>      */
>     protected List appendListOfColumns(String[] columns, StringBuffer buf)
>     {
>         ArrayList columnList = new ArrayList();
> 
>         for (int i = 0; i < columns.length; i++)
>         {
>             if (i > 0)
>             {
>                 buf.append(",");
>             }
>             appendColName(columns[i], false, null, buf);
>             columnList.add(columns[i]);
>         }
>         return columnList;
>     }
> 
>     /**
>      * Answer the SELECT-Sql for the Statement
>      */
>     public String getStatement()
>     {
>         StringBuffer stmt = new StringBuffer(1024);
>         Query query = getQuery();
>         boolean first = true;
>         List orderByFields = null;
>         int[] orderByColumnNumbers = null;
>         String[] attributes = null;
>         String[] joinAttributes = null;
>         Iterator it = getJoinTreeToCriteria().entrySet().iterator();
> 
>         if (query instanceof ReportQuery)
>         {
>             attributes = ((ReportQuery) query).getAttributes();
>             joinAttributes = ((ReportQuery) query).getJoinAttributes();
>         }
> 
>         while (it.hasNext())
>         {
>             Map.Entry entry = (Map.Entry) it.next();
>             Criteria whereCrit = (Criteria) entry.getValue();
>             Criteria havingCrit = query.getHavingCriteria();
>             List columnList;
>             StringBuffer where = new StringBuffer();
>             StringBuffer having = new StringBuffer();
>             List groupByFields = null;
> 
>             // Set correct tree of joins for the current criteria
>             setRoot((TableAlias) entry.getKey());
> 
>             if (whereCrit != null && whereCrit.isEmpty())
>             {
>                 whereCrit = null;
>             }
> 
>             if (havingCrit != null && havingCrit.isEmpty())
>             {
>                 havingCrit = null;
>             }
> 
>             if (first)
>             {
>                 first = false;
>             }
>             else
>             {
>                 stmt.append(" UNION ");
>             }
> 
>             stmt.append("SELECT ");
>             if (query.isDistinct())
>             {
>                 stmt.append("DISTINCT ");
>             }
> 
>             if (attributes == null || attributes.length == 0)
>             {
>                 /**
>                  * MBAIRD: use the appendListofColumnsForSelect, as it finds
>                  * the union of select items for all object mapped to the same table. This
>                  * will allow us to load objects with unique mapping fields that are mapped
>                  * to the same table.
>                  */
>                 columnList = appendListOfColumnsForSelect(getSearchClassDescriptor(), stmt);
>             }
>             else
>             {
>                 columnList = appendListOfColumns(attributes, stmt);
>             }
> 
>             // BRJ:
>             // joinColumns are only used to force the building of a join;
>             // they are not appended to the select-clause !
>             // these columns are used in COUNT-ReportQueries and
>             // are taken from the query the COUNT is based on 
>             if (joinAttributes != null && joinAttributes.length > 0)
>             {
>                 for (int i = 0; i < joinAttributes.length; i++)
>                 {
>                 	// PAW: correct for pathClasses?
> 					//getAttributeInfo(joinAttributes[i], false, null);
> 					getAttributeInfo(joinAttributes[i], false, null, getQuery().getPathClasses());
>                 }
>             }
> 
>             groupByFields = query.getGroupBy();
>             if (groupByFields != null && !groupByFields.isEmpty())
>             {
>                 ensureColumns(groupByFields, columnList, stmt);
>             }
> 
>             orderByFields = query.getOrderBy();
>             if (orderByFields != null && !orderByFields.isEmpty())
>             {
>                 orderByColumnNumbers = ensureColumns(orderByFields, columnList, stmt);
>             }
> 
>             /**
>              * treeder: going to map superclass tables here, 
>              * not sure about the columns, just using all columns for now
>              */
>             ClassDescriptor cld = super.getBaseClassDescriptor();
>             ClassDescriptor cldSuper = null;
>             if (cld.getSuperClass() != null)
>             {
>                 // then we have a super class so join tables
>                 cldSuper = cld.getRepository().getDescriptorFor(cld.getSuperClass());
>                 appendSuperClassColumns(cld, cldSuper, stmt);
>             }
> 
>             stmt.append(" FROM ");
> 
>             appendTableWithJoins(getRoot(), where, stmt);
>             if (cld.getSuperClass() != null)
>             {
>                 appendSuperClassJoin(cld, cldSuper, stmt, where);
>             }
>             
>             appendWhereClause(where, whereCrit, stmt);
>             appendGroupByClause(groupByFields, stmt);
>             appendHavingClause(having, havingCrit, stmt);
>         }
> 
>         appendOrderByClause(orderByFields, orderByColumnNumbers, stmt);
> 
>         return stmt.toString();
>     }
> 
>     private void appendSuperClassJoin(ClassDescriptor cld, ClassDescriptor cldSuper, StringBuffer stmt,
>             StringBuffer where)
>     {
>         stmt.append(",").append(cldSuper.getFullTableName());
>         if (where != null && where.length() > 0)
>         {
>             where.append(" AND ");
>         }
>         // get reference field in super class
>         // TODO: do not use the superclassfield anymore, just assume that the id is the same in both tables - @see PBroker.storeToDb
>         int superFieldRef = cld.getSuperClassFieldRef();
>         FieldDescriptor refField = cld.getFieldDescriptorByIndex(superFieldRef);
>         where.append(cldSuper.getFullTableName()).append(".").append(
>                 cldSuper.getAutoIncrementFields()[0].getColumnName());
>         where.append(" = ");
>         where.append(cld.getFullTableName()).append(".").append(refField.getColumnName());
> 
>     }
> 
>     private void appendSuperClassColumns(ClassDescriptor cldSub, ClassDescriptor cldSuper, StringBuffer buf)
>     {
>         FieldDescriptor[] fields = cldSuper.getFieldDescriptions();
>         for (int i = 0; i < fields.length; i++)
>         {
>             FieldDescriptor field = fields[i];
>             if (i > 0)
>             {
>                 buf.append(",");
>             }
>             buf.append(cldSuper.getFullTableName());
>             buf.append(".");
>             buf.append(field.getColumnName());
>             //columnList.add(field.getAttributeName());
> 
>         }
> 
>     }
> 
> }
> 
> 
> ------------------------------------------------------------------------
> 
> /*
>  * Created on Mar 24, 2004
>  *
>  * To change the template for this generated file go to
>  * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
>  */
> package org.apache.ojb.broker;
> 
> import java.util.ArrayList;
> import java.util.Collection;
> 
> /**
>  * @author phil
>  *
>  * To change the template for this generated type comment go to
>  * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
>  */
> public class A
> {
> 	private long id;
> 	private int aAttrib;
> 	private Collection bSet;
> 	
> 	public A()
> 	{
> 	}
> 	
> 	public A(int aAttrib)
> 	{
> 		this.aAttrib = aAttrib;
> 		this.bSet = new ArrayList();
> 	}
> 	
> 	/**
> 	 * @return
> 	 */
> 	public int getAAttrib()
> 	{
> 		return aAttrib;
> 	}
> 
> 	/**
> 	 * @return
> 	 */
> 	public Collection getBSet()
> 	{
> 		return bSet;
> 	}
> 
> 	/**
> 	 * @return
> 	 */
> 	public long getId()
> 	{
> 		return id;
> 	}
> 
> 	/**
> 	 * @param i
> 	 */
> 	public void setAAttrib(int i)
> 	{
> 		aAttrib = i;
> 	}
> 
> 	/**
> 	 * @param collection
> 	 */
> 	public void setBSet(Collection collection)
> 	{
> 		bSet = collection;
> 	}
> 
> 	/**
> 	 * @param l
> 	 */
> 	public void setId(long l)
> 	{
> 		id = l;
> 	}
> 
> }
> 
> 
> ------------------------------------------------------------------------
> 
> /*
>  * Created on Mar 24, 2004
>  *
>  * To change the template for this generated file go to
>  * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
>  */
> package org.apache.ojb.broker;
> 
> import java.util.ArrayList;
> import java.util.Collection;
> 
> /**
>  * @author phil
>  *
>  * To change the template for this generated type comment go to
>  * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
>  */
> public class B
> {
> 	private long id;
> 	private long aId;
> 	private int bAttrib;
> 	private A a;
> 	private Collection cSet;
> 	
> 	public B()
> 	{
> 	}
> 	
> 	public B(int bAttrib)
> 	{
> 		this.bAttrib = bAttrib;
> 		this.cSet = new ArrayList();
> 	}
> 	
> 	/**
> 	 * @return
> 	 */
> 	public int getBAttrib()
> 	{
> 		return bAttrib;
> 	}
> 
> 	/**
> 	 * @return
> 	 */
> 	public Collection getCSet()
> 	{
> 		return cSet;
> 	}
> 
> 	/**
> 	 * @return
> 	 */
> 	public long getId()
> 	{
> 		return id;
> 	}
> 
> 	/**
> 	 * @param i
> 	 */
> 	public void setBAttrib(int i)
> 	{
> 		bAttrib = i;
> 	}
> 
> 	/**
> 	 * @param collection
> 	 */
> 	public void setCSet(Collection collection)
> 	{
> 		cSet = collection;
> 	}
> 
> 	/**
> 	 * @param l
> 	 */
> 	public void setId(long l)
> 	{
> 		id = l;
> 	}
> 
> 	/**
> 	 * @return
> 	 */
> 	public A getA()
> 	{
> 		return a;
> 	}
> 
> 	/**
> 	 * @param a
> 	 */
> 	public void setA(A a)
> 	{
> 		this.a = a;
> 		a.getBSet().add(this);
> 	}
> 
> }
> 
> 
> ------------------------------------------------------------------------
> 
> package org.apache.ojb.broker.query;
> 
> 
> /* Copyright  2004 The Apache Software Foundation
>  *
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
>  * You may obtain a copy of the License at
>  *
>  *     http://www.apache.org/licenses/LICENSE-2.0
>  *
>  * Unless required by applicable law or agreed to in writing, software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  * See the License for the specific language governing permissions and
>  * limitations under the License.
>  */
> 
> /**
>  * SelectionCriteria for 'between x and y'
>  *
>  * @author <a href="mailto:jbraeuchi@hotmail.com">Jakob Braeuchi</a>
>  * @version $Id: BetweenCriteria.java,v 1.7 2004/03/11 18:16:13 brianm Exp $
>  */
> public class BetweenCriteria extends ValueCriteria
> {
>     private Object value2;
> 
>     BetweenCriteria(Object anAttribute, Object aValue1, Object aValue2, String aClause, String anAlias)
>     {
>         super(anAttribute, aValue1, aClause, anAlias);
>         setValue2(aValue2);
>     }
> 
>     /**
>      * sets the value of the criteria to newValue. 
>      * Used by the ODMG OQLQuery.bind() operation
>      * BRJ: bind get's called twice so we need to know which value to set
>      */
>     public void bind(Object newValue)
>     {
>     	if (getValue() == null)
>     	{
>     		setValue(newValue);
>     	}	
>     	else
>     	{
>     		setValue2(newValue);
>     		setBound(true); 		
>     	}
>     }
> 
> 
> 	/**
> 	 * Gets the value2.
> 	 * @return Returns a Object
> 	 */
> 	public Object getValue2()
> 	{
> 		return value2;
> 	}
> 
> 	/**
> 	 * Sets the value2.
> 	 * @param value2 The value2 to set
> 	 */
> 	protected void setValue2(Object value2)
> 	{
> 		this.value2 = value2;
> 	}
> 
> 	/**
> 	 * @see org.apache.ojb.broker.query.SelectionCriteria#isBindable()
> 	 */
> 	protected boolean isBindable()
> 	{
> 		return (getValue() == null && getValue2() == null);
> 	}
> 
> 	// PAW
> 	/**
> 	 * String representation
> 	 */
> 	public String toString()
> 	{
> 		return super.toString() + " AND " + value2;
> 	}
> }
> 
> 
> 
> ------------------------------------------------------------------------
> 
> /*
>  * Created on Mar 24, 2004
>  *
>  * To change the template for this generated file go to
>  * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
>  */
> package org.apache.ojb.broker;
> 
> /**
>  * @author phil
>  *
>  * To change the template for this generated type comment go to
>  * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
>  */
> public class C1 extends C
> {
> 
> 	private int c1Attrib;
> 	/**
> 	 * @param cAttrib
> 	 */
> 	
> 	public C1()
> 	{
> 	}
> 
> 	public C1(int cAttrib)
> 	{
> 		super(cAttrib);
> 		// TODO Auto-generated constructor stub
> 	}
> 
> 	/**
> 	 * @return
> 	 */
> 	public int getC1Attrib()
> 	{
> 		return c1Attrib;
> 	}
> 
> 	/**
> 	 * @param i
> 	 */
> 	public void setC1Attrib(int i)
> 	{
> 		c1Attrib = i;
> 	}
> 
> }
> 
> 
> ------------------------------------------------------------------------
> 
> /*
>  * Created on Mar 24, 2004
>  *
>  * To change the template for this generated file go to
>  * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
>  */
> package org.apache.ojb.broker;
> 
> /**
>  * @author phil
>  *
>  * To change the template for this generated type comment go to
>  * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
>  */
> public class C
> {
> 	private long id;
> 	private long bId;
> 	private B b;
> 	private long dId;
> 	private D d;
> 	private int cAttrib;
> 	
> 	public C()
> 	{
> 	}
> 
> 	public C(int cAttrib)
> 	{
> 		this.cAttrib = cAttrib;
> 	}
> 	
> 	/**
> 	 * @return
> 	 */
> 	public int getCAttrib()
> 	{
> 		return cAttrib;
> 	}
> 
> 	/**
> 	 * @return
> 	 */
> 	public D getD()
> 	{
> 		return d;
> 	}
> 
> 	/**
> 	 * @return
> 	 */
> 	public long getId()
> 	{
> 		return id;
> 	}
> 
> 	/**
> 	 * @param i
> 	 */
> 	public void setCAttrib(int i)
> 	{
> 		cAttrib = i;
> 	}
> 
> 	/**
> 	 * @param collection
> 	 */
> 	public void setD(D d)
> 	{
> 		this.d = d;
> 	}
> 
> 	/**
> 	 * @param l
> 	 */
> 	public void setId(long l)
> 	{
> 		id = l;
> 	}
> 
> 	/**
> 	 * @return
> 	 */
> 	public B getB()
> 	{
> 		return b;
> 	}
> 
> 	/**
> 	 * @param b
> 	 */
> 	public void setB(B b)
> 	{
> 		this.b = b;
> 		b.getCSet().add(this);
> 	}
> 
> }
> 
> 
> ------------------------------------------------------------------------
> 
> package org.apache.ojb.broker.query;
> 
> /* Copyright  2004 The Apache Software Foundation
>  *
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
>  * You may obtain a copy of the License at
>  *
>  *     http://www.apache.org/licenses/LICENSE-2.0
>  *
>  * Unless required by applicable law or agreed to in writing, software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  * See the License for the specific language governing permissions and
>  * limitations under the License.
>  */
> 
> import java.util.ArrayList;
> import java.util.Collection;
> import java.util.Enumeration;
> import java.util.HashMap;
> import java.util.Iterator;
> import java.util.List;
> import java.util.Map;
> import java.util.Vector;
> 
> import org.apache.ojb.broker.PersistenceBrokerFactory;
> import org.apache.ojb.broker.metadata.FieldHelper;
> import org.apache.ojb.broker.core.PersistenceBrokerConfiguration;
> import org.apache.ojb.broker.util.configuration.ConfigurationException;
> 
> /**
>  * Persistent Criteria can be used to retrieve sets of objects based on their attributes
>  * Normally each attribute is ANDed together, an OR can be performed by creating a new
>  * PersistentCriteria and adding it.
>  * <P>
>  * Criteria are used, rather than a simple string, because they can be precompiled for
>  * efficiency.
>  *
>  * This code is based on stuff from
>  * COBRA - Java Object Persistence Layer
>  * Copyright (C) 1997, 1998    DB Harvey-George
>  * eMail: cobra@lowrent.org
>  *
>  * @author <a href="mailto:jbraeuchi@gmx.ch">Jakob Braeuchi</a>
>  * @version $Id: Criteria.java,v 1.41 2004/03/11 18:16:13 brianm Exp $
>  */
> public class Criteria implements java.io.Serializable
> {
>     static final long serialVersionUID = 7384550404778187808L;
> 
>     /** criteria is OR-ed with it's parent */
>     public static final int OR = 0;
>     /** criteria is AND-ed with it's parent */
>     public static final int AND = 1;
>     /** criteria has no parent */
>     public static final int NONE = 9;
> 
>     /** prefix to identify attributes referencing enclosing query */
>     public static final String PARENT_QUERY_PREFIX = "parentQuery.";
> 
>     private Vector m_criteria;
>     private int m_type;
>     private boolean m_embraced;
>     private boolean m_negative = false;
> 
>     // holding CriteriaFields for orderBy and groupBy
>     private List orderby = null;
>     private List groupby = null;
>     private List prefetchedRelationships = null;
> 
>     // an optional alias to be used for this criteria
>     private String m_alias = null;
> 
>     /** the max. number of parameters in a IN-statement */
>     protected static final int IN_LIMIT = getSqlInLimit();
> 
>     private QueryByCriteria m_query;
>     private Criteria m_parentCriteria;
> 
>     // PAW
> 	// hint classes for paths of this criteria
> 	private Map m_pathClasses;
> 
>     /**
>      * Constructor declaration
>      */
>     public Criteria()
>     {
>         m_criteria = new Vector();
>         groupby = new ArrayList();
>         orderby = new ArrayList();
>         prefetchedRelationships = new ArrayList();
>         m_type = NONE;
>         m_embraced = false;
>         // PAW
> 		m_pathClasses = new HashMap();
>     }
> 
>     /**
>      * Constructor with a SelectionCriteria
>      * @param aSelectionCriteria SelectionCriteria
>      */
>     public Criteria(SelectionCriteria aSelectionCriteria)
>     {
>         this();
>         addSelectionCriteria(aSelectionCriteria);
>     }
> 
>     /**
>      * make a copy of the criteria
>      * @param includeGroupBy if true
>      * @param includeOrderBy if ture
>      * @param includePrefetchedRelationships if true
>      * @return a copy of the criteria
>      */
>     public Criteria copy(boolean includeGroupBy, boolean includeOrderBy, boolean includePrefetchedRelationships)
>     {
>         Criteria copy = new Criteria();
> 
>         copy.m_criteria = this.m_criteria;
>         copy.m_negative = this.m_negative;
> 
>         if (includeGroupBy)
>         {
>             copy.groupby = this.groupby;
>         }
>         if (includeOrderBy)
>         {
>             copy.orderby = this.orderby;
>         }
>         if (includePrefetchedRelationships)
>         {
>             copy.prefetchedRelationships = this.prefetchedRelationships;
>         }
> 
>         return copy;
>     }
> 
>     protected void addSelectionCriteria(SelectionCriteria selectionCrit)
>     {
>         selectionCrit.setCriteria(this);
>         m_criteria.addElement(selectionCrit);
>     }
> 
>     protected void addCriteria(Criteria crit)
>     {
>         crit.setParentCriteria(this);
>         m_criteria.addElement(crit);
>     }
> 
>     protected void addCriteria(Vector criteria)
>     {
>         Object crit;
> 
>         for (int i = 0; i < criteria.size(); i++)
>         {
>             crit = criteria.elementAt(i);
>             if (crit instanceof SelectionCriteria)
>             {
>                 addSelectionCriteria((SelectionCriteria) crit);
>             }
>             else if (crit instanceof Criteria)
>             {
>                 addCriteria((Criteria) crit);
>             }
>         }
>     }
> 
>     /**
>      * Answer a List of InCriteria based on values, each InCriteria
>      * contains only inLimit values
>      * @param attribute
>      * @param values
>      * @param negative
>      * @param inLimit the maximum number of values for IN (-1 for no limit)
>      * @return
>      */
>     protected List splitInCriteria(Object attribute, Collection values, boolean negative, int inLimit)
>     {
>         List result = new ArrayList();
>         Collection inCollection = new ArrayList();
> 
>         if (values == null || values.isEmpty())
>         {
>             // OQL creates empty Criteria for late binding
>             result.add(buildInCriteria(attribute, negative, values));
>         }
>         else
>         {
>             Iterator iter = values.iterator();
> 
>             while (iter.hasNext())
>             {
>                 inCollection.add(iter.next());
>                 if (inCollection.size() == inLimit || !iter.hasNext())
>                 {
>                     result.add(buildInCriteria(attribute, negative, inCollection));
>                     inCollection = new ArrayList();
>                 }
>             }
>         }
>         return result;
>     }
> 
>     private InCriteria buildInCriteria(Object attribute, boolean negative, Collection values)
>     {
>         if (negative)
>         {
>             return ValueCriteria.buildNotInCriteria(attribute, values, getAlias());
>         }
>         else
>         {
>             return ValueCriteria.buildInCriteria(attribute, values, getAlias());
>         }
>     }
> 
>     /**
>      * Get an Enumeration with all sub criteria
>      * @return Enumeration
>      */
>     public Enumeration getElements()
>     {
>         return getCriteria().elements();
>     }
> 
>     /**
>      * Get a Vector with all sub criteria
>      * @return Vector
>      */
>     protected Vector getCriteria()
>     {
>         return m_criteria;
>     }
> 
>     /**
>      * Answer the type
>      * @return int
>      */
>     public int getType()
>     {
>         return m_type;
>     }
> 
>     /**
>      * Set the type
>      * @param type OR, AND, NONE
>      */
>     public void setType(int type)
>     {
>         m_type = type;
>     }
> 
>     /**
>      * ANDed criteria are embraced
>      * @return true if embraced,
>      */
>     public boolean isEmbraced()
>     {
>         return m_embraced;
>     }
> 
>     /**
>      * Set embraced
>      * @param embraced true if criteria is to be surrounded by braces
>      */
>     public void setEmbraced(boolean embraced)
>     {
>         m_embraced = embraced;
>     }
> 
>     /**
>      * Adds and equals (=) criteria,
>      * customer_id = 10034
>      *
>      * @param  attribute   The field name to be used
>      * @param  value       An object representing the value of the field
>      */
>     public void addEqualTo(String attribute, Object value)
>     {
>         addSelectionCriteria(ValueCriteria.buildEqualToCriteria(attribute, value, getAlias()));
>     }
> 
>     /**
>      * Adds and equals (=) criteria,
>      * CUST_ID = 10034
>      * attribute will NOT be translated into column name
>      *
>      * @param  column   The column name to be used without translation
>      * @param  value    An object representing the value of the column
>      */
>     public void addColumnEqualTo(String column, Object value)
>     {
>         SelectionCriteria c = ValueCriteria.buildEqualToCriteria(column, value, getAlias());
>         c.setTranslateAttribute(false);
>         addSelectionCriteria(c);
>     }
> 
>     /**
>      * Adds and equals (=) criteria for field comparison.
>      * The field name will be translated into the appropriate columnName by SqlStatement.
>      * The attribute will NOT be translated into column name
>      *
>      * @param  column       The column name to be used without translation
>      * @param  fieldName    An object representing the value of the field
>      */
>     public void addColumnEqualToField(String column, Object fieldName)
>     {
>         SelectionCriteria c = FieldCriteria.buildEqualToCriteria(column, fieldName, getAlias());
>         c.setTranslateAttribute(false);
>         addSelectionCriteria(c);
>     }
> 
>     /**
>      * Adds and equals (=) criteria for field comparison.
>      * The field name will be translated into the appropriate columnName by SqlStatement.
>      * <br>
>      * name = boss.name
>      *
>      * @param  attribute   The field name to be used
>      * @param  fieldName   The field name to compare with
>      */
>     public void addEqualToField(String attribute, String fieldName)
>     {
>         FieldCriteria c = FieldCriteria.buildEqualToCriteria(attribute, fieldName, getAlias());
>         addSelectionCriteria(c);
>     }
> 
>     /**
>      * Adds and equals (=) criteria for field comparison.
>      * The field name will be translated into the appropriate columnName by SqlStatement.
>      * <br>
>      * name <> boss.name
>      *
>      * @param  attribute   The field name to be used
>      * @param  fieldName   The field name to compare with
>      */
>     public void addNotEqualToField(String attribute, String fieldName)
>     {
>         SelectionCriteria c = FieldCriteria.buildNotEqualToCriteria(attribute, fieldName, getAlias());
>         addSelectionCriteria(c);
>     }
> 
>     /**
>      * Adds and equals (<>) criteria for column comparison.
>      * The column Name will NOT be translated.
>      * <br>
>      * name <> T_BOSS.LASTNMAE
>      *
>      * @param  attribute   The field name to be used
>      * @param  colName     The name of the column to compare with
>      */
>     public void addNotEqualToColumn(String attribute, String colName)
>     {
>         FieldCriteria c = FieldCriteria.buildNotEqualToCriteria(attribute, colName, getAlias());
>         c.setTranslateField(false);
>         addSelectionCriteria(c);
>     }
> 
>     /**
>      * Adds and equals (=) criteria for column comparison.
>      * The column Name will NOT be translated.
>      * <br>
>      * name = T_BOSS.LASTNMAE
>      *
>      * @param  attribute   The field name to be used
>      * @param  colName     The name of the column to compare with
>      */
>     public void addEqualToColumn(String attribute, String colName)
>     {
>         FieldCriteria c = FieldCriteria.buildEqualToCriteria(attribute, colName, getAlias());
>         c.setTranslateField(false);
>         addSelectionCriteria(c);
>     }
> 
>     /**
>      * Adds GreaterOrEqual Than (>=) criteria,
>      * customer_id >= 10034
>      *
>      * @param  attribute   The field name to be used
>      * @param  value       An object representing the value of the field
>      */
>     public void addGreaterOrEqualThan(Object attribute, Object value)
>     {
>         addSelectionCriteria(ValueCriteria.buildNotLessCriteria(attribute, value, getAlias()));
>     }
> 
>     /**
>      * Adds GreaterOrEqual Than (>=) criteria,
>      * customer_id >= person_id
>      *
>      * @param  attribute   The field name to be used
>      * @param  value       The field name to compare with
>      */
>     public void addGreaterOrEqualThanField(String attribute, Object value)
>     {
>         addSelectionCriteria(FieldCriteria.buildNotLessCriteria(attribute, value, getAlias()));
>     }
> 
>     /**
>      * Adds LessOrEqual Than (<=) criteria,
>      * customer_id <= 10034
>      *
>      * @param  attribute   The field name to be used
>      * @param  value       An object representing the value of the field
>      */
>     public void addLessOrEqualThan(Object attribute, Object value)
>     {
>         addSelectionCriteria(ValueCriteria.buildNotGreaterCriteria(attribute, value, getAlias()));
>     }
> 
>     /**
>      * Adds LessOrEqual Than (<=) criteria,
>      * customer_id <= person_id
>      *
>      * @param  attribute   The field name to be used
>      * @param  value       The field name to compare with
>      */
>     public void addLessOrEqualThanField(String attribute, Object value)
>     {
>         addSelectionCriteria(FieldCriteria.buildNotGreaterCriteria(attribute, value, getAlias()));
>     }
> 
>     /**
>      * Adds Like (LIKE) criteria,
>      * customer_name LIKE "m%ller"
>      *
>      * @see LikeCriteria
>      * @param  attribute   The field name to be used
>      * @param  value       An object representing the value of the field
>      */
>     public void addLike(Object attribute, Object value)
>     {
>         addSelectionCriteria(ValueCriteria.buildLikeCriteria(attribute, value, getAlias()));
>     }
> 
>     /**
>      * Adds Like (NOT LIKE) criteria,
>      * customer_id NOT LIKE 10034
>      *
>      * @see LikeCriteria
>      * @param  attribute   The field name to be used
>      * @param  value       An object representing the value of the field
>      */
>     public void addNotLike(String attribute, Object value)
>     {
>         addSelectionCriteria(ValueCriteria.buildNotLikeCriteria(attribute, value, getAlias()));
>     }
> 
>     /**
>      * Adds NotEqualTo (<>) criteria,
>      * customer_id <> 10034
>      *
>      * @param  attribute   The field name to be used
>      * @param  value       An object representing the value of the field
>      */
>     public void addNotEqualTo(Object attribute, Object value)
>     {
>         addSelectionCriteria(ValueCriteria.buildNotEqualToCriteria(attribute, value, getAlias()));
>     }
> 
>     /**
>      * Adds Greater Than (>) criteria,
>      * customer_id > 10034
>      *
>      * @param  attribute   The field name to be used
>      * @param  value       An object representing the value of the field
>      */
>     public void addGreaterThan(Object attribute, Object value)
>     {
>         addSelectionCriteria(ValueCriteria.buildGreaterCriteria(attribute, value, getAlias()));
>     }
> 
>     /**
>      * Adds Greater Than (>) criteria,
>      * customer_id > person_id
>      *
>      * @param  attribute   The field name to be used
>      * @param  value       The field to compare with
>      */
>     public void addGreaterThanField(String attribute, Object value)
>     {
>         addSelectionCriteria(FieldCriteria.buildGreaterCriteria(attribute, value, getAlias()));
>     }
> 
>     /**
>      * Adds Less Than (<) criteria,
>      * customer_id < 10034
>      *
>      * @param  attribute   The field name to be used
>      * @param  value       An object representing the value of the field
>      */
>     public void addLessThan(Object attribute, Object value)
>     {
>         addSelectionCriteria(ValueCriteria.buildLessCriteria(attribute, value, getAlias()));
>     }
> 
>     /**
>      * Adds Less Than (<) criteria,
>      * customer_id < person_id
>      *
>      * @param  attribute   The field name to be used
>      * @param  value       The field to compare with
>      */
>     public void addLessThanField(String attribute, Object value)
>     {
>         addSelectionCriteria(FieldCriteria.buildLessCriteria(attribute, value, getAlias()));
>     }
> 
>     /**
>      * Adds a field for orderBy, order is ASCENDING
>      * @param  fieldName The field name to be used
>      * @deprecated use #addOrderByAscending(String fieldName)
>      */
>     public void addOrderBy(String fieldName)
>     {
>         addOrderBy(fieldName, true);
>     }
> 
>     /**
>      * Adds a field for orderBy
>      * @param  fieldName the field name to be used
>      * @param  sortAscending true for ASCENDING, false for DESCENDING
>      */
>     public void addOrderBy(String fieldName, boolean sortAscending)
>     {
>         if (fieldName != null)
>         {
>             _getOrderby().add(new FieldHelper(fieldName, sortAscending));
>         }
>     }
> 
>     /**
>      * Adds a field for orderBy
>      * @param aField the Field
>      * @deprecated use QueryByCriteria#addOrderBy
>      */
>     public void addOrderBy(FieldHelper aField)
>     {
>         if (aField != null)
>         {
>             _getOrderby().add(aField);
>         }
>     }
> 
>     /**
>      * Adds a field for orderBy ASCENDING
>      * @param  fieldName The field name to be used
>      * @deprecated use QueryByCriteria#addOrderByAscending
>      */
>     public void addOrderByAscending(String fieldName)
>     {
>         addOrderBy(fieldName, true);
>     }
> 
>     /**
>      * Adds a field for orderBy DESCENDING
>      * @param  fieldName The field name to be used
>      * @deprecated use QueryByCriteria#addOrderByDescending
>      */
>     public void addOrderByDescending(String fieldName)
>     {
>         addOrderBy(fieldName, false);
>     }
> 
>     /**
>      * Answer the orderBy of all Criteria and Sub Criteria
>      * the elements are of class Criteria.FieldHelper
>      * @return List
>      */
>     List getOrderby()
>     {
>         List result = _getOrderby();
>         Iterator iter = getCriteria().iterator();
>         Object crit;
> 
>         while (iter.hasNext())
>         {
>             crit = iter.next();
>             if (crit instanceof Criteria)
>             {
>                 result.addAll(((Criteria) crit).getOrderby());
>             }
>         }
> 
>         return result;
>     }
> 
>     /**
>      * Answer the Vector with all orderBy,
>      * the elements are of class Criteria.FieldHelper
>      * @return List
>      */
>     protected List _getOrderby()
>     {
>         return orderby;
>     }
> 
>     /**
>      * ORs two sets of criteria together:
>      * <pre>
>      * active = true AND balance < 0 OR active = true AND overdraft = 0
>      * </pre>
>      * @param pc criteria
>      */
>     public void addOrCriteria(Criteria pc)
>     {
>         if (!m_criteria.isEmpty())
>         {
>             pc.setEmbraced(true);
>             pc.setType(OR);
>             addCriteria(pc);
>         }
>         else
>         {
>             setEmbraced(false);
>             pc.setType(OR);
>             addCriteria(pc);
>         }
>     }
> 
>     /**
>      * Adds is Null criteria,
>      * customer_id is Null
>      *
>      * @param  attribute   The field name to be used
>      */
>     public void addIsNull(String attribute)
>     {
>         addSelectionCriteria(ValueCriteria.buildNullCriteria(attribute, getAlias()));
>     }
> 
>     /**
>      * Adds is Null criteria,
>      * customer_id is Null
>      * The attribute will NOT be translated into column name
>      *
>      * @param  column   The column name to be used without translation
>      */
>     public void addColumnIsNull(String column)
>     {
>         SelectionCriteria c = ValueCriteria.buildNullCriteria(column, getAlias());
>         c.setTranslateAttribute(false);
>         addSelectionCriteria(c);
>     }
> 
>     /**
>      * Adds not Null criteria,
>      * customer_id is not Null
>      *
>      * @param  attribute   The field name to be used
>      */
>     public void addNotNull(String attribute)
>     {
>         addSelectionCriteria(ValueCriteria.buildNotNullCriteria(attribute, getAlias()));
>     }
> 
>     /**
>      * Adds not Null criteria,
>      * customer_id is not Null
>      * The attribute will NOT be translated into column name
>      *
>      * @param  column   The column name to be used without translation
>      */
>     public void addColumnNotNull(String column)
>     {
>         SelectionCriteria c = ValueCriteria.buildNotNullCriteria(column, getAlias());
>         c.setTranslateAttribute(false);
>         addSelectionCriteria(c);
>     }
> 
>     /**
>      * Adds BETWEEN criteria,
>      * customer_id between 1 and 10
>      *
>      * @param  attribute   The field name to be used
>      * @param  value1   The lower boundary
>      * @param  value2   The upper boundary
>      */
>     public void addBetween(Object attribute, Object value1, Object value2)
>     {
>         addSelectionCriteria(ValueCriteria.buildBeweenCriteria(attribute, value1, value2, getAlias()));
>     }
> 
>     /**
>      * Adds NOT BETWEEN criteria,
>      * customer_id not between 1 and 10
>      *
>      * @param  attribute   The field name to be used
>      * @param  value1   The lower boundary
>      * @param  value2   The upper boundary
>      */
>     public void addNotBetween(Object attribute, Object value1, Object value2)
>     {
>         addSelectionCriteria(ValueCriteria.buildNotBeweenCriteria(attribute, value1, value2, getAlias()));
>     }
> 
>     /**
>      * Adds IN criteria,
>      * customer_id in(1,10,33,44)
>      * large values are split into multiple InCriteria
>      * IN (1,10) OR IN(33, 44)
>      *
>      * @param  attribute   The field name to be used
>      * @param  values   The value Collection
>      */
>     public void addIn(String attribute, Collection values)
>     {
>         List list = splitInCriteria(attribute, values, false, IN_LIMIT);
>         int index = 0;
>         InCriteria inCrit;
>         Criteria allInCritaria;
> 
>         inCrit = (InCriteria) list.get(index);
>         allInCritaria = new Criteria(inCrit);
> 
>         for (index = 1; index < list.size(); index++)
>         {
>             inCrit = (InCriteria) list.get(index);
>             allInCritaria.addOrCriteria(new Criteria(inCrit));
>         }
> 
>         addAndCriteria(allInCritaria);
>     }
> 
>     /**
>      * Adds IN criteria,
>      * customer_id in(1,10,33,44)
>      * large values are split into multiple InCriteria
>      * IN (1,10) OR IN(33, 44) </br>
>      * The attribute will NOT be translated into column name
>      *
>      * @param  column   The column name to be used without translation
>      * @param  values   The value Collection
>      */
>     public void addColumnIn(String column, Collection values)
>     {
>         List list = splitInCriteria(column, values, false, IN_LIMIT);
>         int index = 0;
>         InCriteria inCrit;
>         Criteria allInCritaria;
> 
>         inCrit = (InCriteria) list.get(index);
>         inCrit.setTranslateAttribute(false);
>         allInCritaria = new Criteria(inCrit);
> 
>         for (index = 1; index < list.size(); index++)
>         {
>             inCrit = (InCriteria) list.get(index);
>             inCrit.setTranslateAttribute(false);
>             allInCritaria.addOrCriteria(new Criteria(inCrit));
>         }
> 
>         addAndCriteria(allInCritaria);
>     }
>     
>     /**
>      * Adds NOT IN criteria,
>      * customer_id not in(1,10,33,44)
>      * large values are split into multiple InCriteria
>      * NOT IN (1,10) AND NOT IN(33, 44)
>      *
>      * @param  attribute   The field name to be used
>      * @param  values   The value Collection
>      */
>     public void addNotIn(String attribute, Collection values)
>     {
>         List list = splitInCriteria(attribute, values, true, IN_LIMIT);
>         int index = 0;
>         InCriteria inCrit;
> 
>         for (index = 0; index < list.size(); index++)
>         {
>             inCrit = (InCriteria) list.get(index);
>             addSelectionCriteria(inCrit);
>         }
>     }
> 
>     /**
>      * IN Criteria with SubQuery
>      * @param attribute The field name to be used
>      * @param subQuery  The subQuery
>      */
>     public void addIn(Object attribute, Query subQuery)
>     {
>         addSelectionCriteria(ValueCriteria.buildInCriteria(attribute, subQuery, getAlias()));
>     }
> 
>     /**
>      * NOT IN Criteria with SubQuery
>      * @param attribute The field name to be used
>      * @param subQuery  The subQuery
>      */
>     public void addNotIn(String attribute, Query subQuery)
>     {
>         addSelectionCriteria(ValueCriteria.buildNotInCriteria(attribute, subQuery, getAlias()));
>     }
> 
>     /**
>      * Adds freeform SQL criteria,
>      * REVERSE(name) like 're%'
>      *
>      * @param  anSqlStatment   The free form SQL-Statement
>      */
>     public void addSql(String anSqlStatment)
>     {
>         addSelectionCriteria(new SqlCriteria(anSqlStatment));
>     }
> 
>     /**
>      * ANDs two sets of criteria together:
>      *
>      * @param  pc criteria
>      */
>     public void addAndCriteria(Criteria pc)
>     {
>         // by combining a second criteria by 'AND' the existing criteria needs to be enclosed
>         // in parenthesis
>         if (!m_criteria.isEmpty())
>         {
>             this.setEmbraced(true);
>             pc.setEmbraced(true);
>             pc.setType(AND);
>             addCriteria(pc);
>         }
>         else
>         {
>             setEmbraced(false);
>             pc.setType(AND);
>             addCriteria(pc);
>         }
>     }
> 
>     /**
>      * Adds an exists(sub query)
>      *
>      * @param subQuery sub-query
>      */
>     public void addExists(Query subQuery)
>     {
>         addSelectionCriteria(new ExistsCriteria(subQuery, false));
>     }
> 
>     /**
>      * Adds a not exists(sub query)
>      *
>      * @param subQuery sub-query
>      */
>     public void addNotExists(Query subQuery)
>     {
>         addSelectionCriteria(new ExistsCriteria(subQuery, true));
>     }
> 
>     /**
>      * Answer true if no sub criteria available
>      * @return boolean
>      */
>     public boolean isEmpty()
>     {
>         return m_criteria.isEmpty();
>     }
> 
>     /**
>      * Gets the groupby for ReportQueries of all Criteria and Sub Criteria
>      * the elements are of class FieldHelper
>      * @return List of FieldHelper
>      */
>     List getGroupby()
>     {
>         List result = _getGroupby();
>         Iterator iter = getCriteria().iterator();
>         Object crit;
> 
>         while (iter.hasNext())
>         {
>             crit = iter.next();
>             if (crit instanceof Criteria)
>             {
>                 result.addAll(((Criteria) crit).getGroupby());
>             }
>         }
> 
>         return result;
>     }
> 
>     /**
>      * Gets the groupby for ReportQueries,
>      * the elements are of class Criteria.FieldHelper
>      * @return List of Criteria.FieldHelper
>      */
>     protected List _getGroupby()
>     {
>         return groupby;
>     }
> 
>     /**
>      * Adds a groupby fieldName for ReportQueries.
>      * @param fieldName The groupby to set
>      * @deprecated use QueryByCriteria#addGroupBy
>      */
>     public void addGroupBy(String fieldName)
>     {
>         if (fieldName != null)
>         {
>             _getGroupby().add(new FieldHelper(fieldName, false));
>         }
>     }
> 
>     /**
>      * Adds a field for groupby
>      * @param aField the Field
>      * @deprecated use QueryByCriteria#addGroupBy
>      */
>     public void addGroupBy(FieldHelper aField)
>     {
>         if (aField != null)
>         {
>             _getGroupby().add(aField);
>         }
>     }
> 
>     /**
>      * Adds an array of groupby fieldNames for ReportQueries.
>      * @param fieldNames The groupby to set
>      * @deprecated use QueryByCriteria#addGroupBy
>      */
>     public void addGroupBy(String[] fieldNames)
>     {
>         for (int i = 0; i < fieldNames.length; i++)
>         {
>             addGroupBy(fieldNames[i]);
>         }
>     }
> 
>     /**
>      * Returns the prefetchedRelationships.
>      * @return List
>      */
>     List getPrefetchedRelationships()
>     {
>         return prefetchedRelationships;
>     }
> 
>     /**
>      * add the name of a Relationship for prefetch read
>      * @param aName the name of the relationship
>      * @deprecated use QueryByCriteria#addPrefetchedRelationship
>      */
>     public void addPrefetchedRelationship(String aName)
>     {
>         getPrefetchedRelationships().add(aName);
>     }
> 
>     /**
>      * read the prefetchInLimit from Config based on OJB.properties
>      */
>     private static int getSqlInLimit()
>     {
>         try
>         {
>             PersistenceBrokerConfiguration config = (PersistenceBrokerConfiguration) PersistenceBrokerFactory
>                     .getConfigurator().getConfigurationFor(null);
>             return config.getSqlInLimit();
>         }
>         catch (ConfigurationException e)
>         {
>             return 200;
>         }
>     }
> 
>     /**
>      * @return String
>      */
>     public String getAlias()
>     {
>         return m_alias;
>     }
> 
>     /**
>      * Sets the alias. Empty String is regarded as null.
>      * @param alias The alias to set
>      */
>     public void setAlias(String alias)
>     {
>         if (alias == null || alias.trim().equals(""))
>         {
>             m_alias = null;
>         }
>         else
>         {
>             m_alias = alias;
>         }
> 
>         // propagate to SelectionCriteria,not to Criteria
>         for (int i = 0; i < m_criteria.size(); i++)
>         {
>             if (!(m_criteria.elementAt(i) instanceof Criteria))
>             {
>                 ((SelectionCriteria) m_criteria.elementAt(i)).setAlias(m_alias);
>             }
>         }
>     }
> 
>     /**
>      * @return the query containing the criteria
>      */
>     public QueryByCriteria getQuery()
>     {
>         if (getParentCriteria() != null)
>         {
>             return getParentCriteria().getQuery();
>         }
>         else
>         {
>             return m_query;
>         }
> 
>     }
> 
>     /**
>      * @param query
>      */
>     void setQuery(QueryByCriteria query)
>     {
>         m_query = query;
>     }
> 
>     /**
>      * @return the parent criteria
>      */
>     public Criteria getParentCriteria()
>     {
>         return m_parentCriteria;
>     }
> 
>     /**
>      * @param criteria
>      */
>     void setParentCriteria(Criteria criteria)
>     {
>         m_parentCriteria = criteria;
>     }
> 
>     /**
>      * @see Object#toString()
>      */
>     public String toString()
>     {
>         if (isNegative())
>         {
>             return "-" + m_criteria.toString();
>         }
>         else
>         {
>             return m_criteria.toString();
>         }
>     }
> 
>     /**
>      * @return Returns the negative.
>      */
>     public boolean isNegative()
>     {
>         return m_negative;
>     }
> 
>     /**
>      * Flags the whole Criteria as negative.
>      * @param negative The negative to set.
>      */
>     public void setNegative(boolean negative)
>     {
>         m_negative = negative;
>     }
> 
> 	// PAW    
> 	/**
> 	 * Add a hint Class for a path. Used for relationships to extents.<br>
> 	 * SqlStatment will use these hint classes when resolving the path.
> 	 * Without these hints SqlStatment will use the base class the
> 	 * relationship points to ie: Article instead of CdArticle.
> 	 *
> 	 * @param aPath the path segment ie: allArticlesInGroup
> 	 * @param aClass the Class ie: CdArticle
> 	 * @see org.apache.ojb.broker.QueryTest#testInversePathExpression()
> 	 */
> 	public void addPathClass(String aPath, Class aClass)
> 	{
> 		Object pathClasses = m_pathClasses.get(aPath);
> 		if(pathClasses == null)
> 		{
> 			setPathClass(aPath,aClass);
> 		}
> 		else
> 		{
> 			List hints = (List)pathClasses;
> 			hints.add(aClass);
> 			m_pathClasses.put(aPath, hints);
> 		}
> 	}
> 
> 	/**
> 	 * Set the Class for a path. Used for relationships to extents.<br>
> 	 * SqlStatment will use this class when resolving the path.
> 	 * Without this hint SqlStatment will use the base class the
> 	 * relationship points to ie: Article instead of CdArticle.
> 	 * Using this method is the same as adding just one hint
> 	 *
> 	 * @param aPath the path segment ie: allArticlesInGroup
> 	 * @param aClass the Class ie: CdArticle
> 	 * @see org.apache.ojb.broker.QueryTest#testInversePathExpression()
> 	 * @see #addPathClass
> 	 */
> 	public void setPathClass(String aPath, Class aClass)
> 	{
> 		List pathClasses = new ArrayList(1);
> 		pathClasses.add(aClass);
> 		m_pathClasses.put(aPath, pathClasses);
> 	}
> 
> 	/**
> 	 * Get the a List of Class objects used as hints for a path
> 	 *
> 	 * @param aPath the path segment ie: allArticlesInGroup
> 	 * @return a List o Class objects to be used in SqlStatment
> 	 * @see #addPathClass
> 	 * @see org.apache.ojb.broker.QueryTest#testInversePathExpression()
> 	 */
> 	public List getClassesForPath(String aPath)
> 	{
> 		return (List)getPathClasses().get(aPath);
> 	}
> 	
> 	/**
> 	 * Gets the pathClasses.
> 	 * A Map containing hints about what Class to be used for what path segment
> 	 * If local instance not set, try parent Criteria's instance.  If this is 
> 	 * the top-level Criteria, try the m_query's instance
> 	 * @return Returns a Map
> 	 */
> 	public Map getPathClasses()
> 	{
> 		if (m_pathClasses.isEmpty())
> 		{
> 			if (m_parentCriteria == null)
> 			{
> 				if (m_query == null)
> 				{
> 					return m_pathClasses;
> 				}
> 				else
> 				{
> 					return m_query.getPathClasses();
> 				}
> 			}
> 			else
> 			{
> 				return m_parentCriteria.getPathClasses();
> 			}
> 		}
> 		else
> 		{
> 			return m_pathClasses;
> 		}
> 	}
> 
> 	
> 
> }
> 
> 
> ------------------------------------------------------------------------
> 
> /*
>  * Created on Mar 24, 2004
>  *
>  * To change the template for this generated file go to
>  * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
>  */
> package org.apache.ojb.broker;
> /**
>  * @author phil
>  *
>  * To change the template for this generated type comment go to
>  * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
>  */
> public class D
> {
> 	private long id;
> 	private int dAttrib;
> 	
> 	public D()
> 	{
> 	}
> 
> 	public D(int dAttrib)
> 	{
> 		this.dAttrib = dAttrib;
> 	}
> 	
> 	/**
> 	 * @return
> 	 */
> 	public int getDAttrib()
> 	{
> 		return dAttrib;
> 	}
> 
> 	/**
> 	 * @return
> 	 */
> 	public long getId()
> 	{
> 		return id;
> 	}
> 
> 	/**
> 	 * @param i
> 	 */
> 	public void setDAttrib(int i)
> 	{
> 		dAttrib = i;
> 	}
> 
> 
> 	/**
> 	 * @param l
> 	 */
> 	public void setId(long l)
> 	{
> 		id = l;
> 	}
> 
> }
> 
> 
> ------------------------------------------------------------------------
> 
>     <!-- ************************************************* -->
>     <!--      Classes for path tests				       -->
>     <!-- ************************************************* -->
> 
>   <table name="A_TABLE">
>     <column name="ID" required="true" primaryKey="true" type="BIGINT"/>
>     <column name="A_ATTRIB" type="INTEGER" required="false"/>
>   </table>
> 
>   <table name="B_TABLE">
>     <column name="ID" required="true" primaryKey="true" type="BIGINT"/>
>     <column name="B_ATTRIB" type="INTEGER" required="false"/>
>     <column name="A_ID" type="BIGINT" required="true"/>
>     <foreign-key foreignTable="A_TABLE">
>       <reference local="A_ID" foreign="ID"/>
>     </foreign-key>
>   </table>
> 
>   <table name="C_TABLE">
>     <column name="ID" required="true" primaryKey="true" type="BIGINT"/>
>     <column name="C_ATTRIB" type="INTEGER" required="false"/>
>     <column name="C1_ATTRIB" type="INTEGER" required="false"/>
>     <column name="B_ID" type="BIGINT" required="true"/>
>     <column name="D_ID" type="BIGINT" required="false"/>
>     <foreign-key foreignTable="B_TABLE">
>       <reference local="B_ID" foreign="ID"/>
>     </foreign-key>
>   </table>
> 
>   <table name="D_TABLE">
>     <column name="ID" required="true" primaryKey="true" type="BIGINT"/>
>     <column name="D_ATTRIB" type="INTEGER" required="false"/>
>   </table>
> 
> 
> ------------------------------------------------------------------------
> 
> /*
>  * Created on Jul 13, 2003
>  *
>  * To change the template for this generated file go to
>  * Window>Preferences>Java>Code Generation>Code and Comments
>  */
> package org.apache.ojb.broker;
> 
> /**
>  * @author Administrator
>  *
>  * To change the template for this generated type comment go to
>  * Window>Preferences>Java>Code Generation>Code and Comments
>  */
> import junit.framework.TestCase;
> 
> import org.apache.ojb.broker.query.Criteria;
> import org.apache.ojb.broker.query.Query;
> import org.apache.ojb.broker.query.QueryByCriteria;
> import org.apache.ojb.broker.query.QueryFactory;
> 
> import java.util.Collection;
> import java.util.Date;
> import java.util.Iterator;
> 
> public class PathTest extends TestCase
> {
> 
> 	private static Class CLASS = PathTest.class;
> 	private int COUNT = 10;
> 	private int id_filter = 10000;
> 	private PersistenceBroker broker = null;
> 
> 	public static void main(String[] args)
> 	{
> 		String[] arr = {CLASS.getName()};
> 		junit.textui.TestRunner.main(arr);
> 	}
> 
> 	/**
> 	 * Insert the method's description here.
> 	 * Creation date: (06.12.2000 21:58:53)
> 	 */
> 	public void setUp()
> 	{
> 		 try
> 		 {
> 			 System.out.println("Begin time: " + new Date());
> 			 broker = PersistenceBrokerFactory.createPersistenceBroker("repository.xml", "MOND_ADMIN", "MOND_ADMIN");
> 		 }
> 		 catch (Throwable t)
> 		 {
> 			 t.printStackTrace();
> 		 }
> 	}
> 
> 	/**
> 	 * Insert the method's description here.
> 	 * Creation date: (06.12.2000 21:59:14)
> 	 */
> 	public void tearDown()
> 	{
> 		System.out.println("End time: " + new Date());
> 	}
> 
> 	public PathTest(String name)
> 	{
> 		super(name);
> 	}
> 
> 	public void testDeleteData() throws Exception
> 	{
> 		broker.beginTransaction();
> 		Criteria crit = new Criteria();
> 		
> 		Query query = QueryFactory.newQuery(D.class, crit);
> 		Collection Ds = broker.getCollectionByQuery(query);
> 		for (Iterator iterator = Ds.iterator(); iterator.hasNext();)
> 		{
> 			broker.delete(iterator.next());
> 		}
> 		query = QueryFactory.newQuery(C.class, crit);
> 		Collection Cs = broker.getCollectionByQuery(query);
> 		for (Iterator iterator = Cs.iterator(); iterator.hasNext();)
> 		{
> 			broker.delete(iterator.next());
> 		}
> 		query = QueryFactory.newQuery(B.class, crit);
> 		Collection Bs = broker.getCollectionByQuery(query);
> 		for (Iterator iterator = Bs.iterator(); iterator.hasNext();)
> 		{
> 			broker.delete(iterator.next());
> 		}
> 		query = QueryFactory.newQuery(A.class, crit);
> 		Collection As = broker.getCollectionByQuery(query);
> 		for (Iterator iterator = As.iterator(); iterator.hasNext();)
> 		{
> 			broker.delete(iterator.next());
> 		}
> 		broker.commitTransaction();
> 	}
> 	
> 	private static int NUM_A = 1;
> 	private static int NUM_B_PER_A = 4;
> 	private static int NUM_C_PER_B = 2;
> 	private static int NUM_C1_PER_B = 3;
> 	private static int NUM_D_PER_C = 1;
> 	
> 	private static int A_OFFSET = 10000;
> 	private static int B_OFFSET = 1000;
> 	private static int C_OFFSET = 100;
> 	private static int D_OFFSET = 10;
> 	public void testCreateData() throws Exception
> 	{
> 		broker.beginTransaction();		
> 		A a = new A(A_OFFSET);
> 		broker.store(a);
> 		for (int i=0; i < NUM_B_PER_A; i++)
> 		{
> 			B b = new B(A_OFFSET + B_OFFSET*i);
> 			b.setA(a);
> 			broker.store(b);
> 			for (int j=0; j < NUM_C_PER_B; j++)
> 			{
> 				C c = new C(A_OFFSET + B_OFFSET*i + C_OFFSET*j);
> 				c.setB(b);
> 				D d = new D(A_OFFSET + B_OFFSET*i + C_OFFSET*j + D_OFFSET); 
> 				c.setD(d);
> 				broker.store(d);
> 				broker.store(c);
> 			}
> 			for (int j=0; j < NUM_C1_PER_B; j++)
> 			{
> 				C1 c1 = new C1(A_OFFSET + B_OFFSET*i + C_OFFSET*j);
> 				c1.setB(b);
> 				D d = new D(A_OFFSET + B_OFFSET*i + C_OFFSET*j + D_OFFSET); 
> 				c1.setD(d);
> 				c1.setC1Attrib(c1.getCAttrib()+1);
> 				broker.store(d);
> 				broker.store(c1);
> 			}
> 		}
> 		broker.commitTransaction();
> 				
> 		broker.clearCache();
> 
> 		Criteria crit = new Criteria();
> 		
> 		Query query = QueryFactory.newQuery(A.class, crit);
> 		Collection As = broker.getCollectionByQuery(query);
> 		assertEquals(As.size(), NUM_A);
> 	
> 		query = QueryFactory.newQuery(B.class, crit);
> 		Collection Bs = broker.getCollectionByQuery(query);
> 		int numB = NUM_A*NUM_B_PER_A;
> 		assertEquals(Bs.size(), numB);
> 	
> 		query = QueryFactory.newQuery(C.class, crit);
> 		Collection Cs = broker.getCollectionByQuery(query);
> 		int numC = numB * (NUM_C_PER_B+NUM_C1_PER_B);
> 		assertEquals(Cs.size(), numC);
> 	
> 		query = QueryFactory.newQuery(D.class, crit);
> 		Collection Ds = broker.getCollectionByQuery(query);
> 		int numD = numC * NUM_D_PER_C;
> 		assertEquals(Ds.size(), numD);
> 	
> 	}
> 
> 	public void testPathClassPerCriteria() throws Exception
> 	{
> 		try
> 		{
> 			// one EDBranch
> 			Criteria crit1 = new Criteria();
> 			crit1.setAlias("alias1");
> 			crit1.addEqualTo("cSet.cAttrib", new Integer("10200"));
> 			crit1.addPathClass("cSet", C.class); 
> 
> 			// one EDLeaf
> 			Criteria crit2 = new Criteria();
> 			crit2.setAlias("alias2");
> 			crit2.addEqualTo("cSet.c1Attrib", new Integer("10001"));
> 			crit2.addPathClass("cSet", C1.class); 
> 			
> 			crit1.addAndCriteria(crit2);
> 			
> 			Query query = new QueryByCriteria(B.class, crit1);
> 
> 			Collection allBs = broker.getCollectionByQuery(query);
> 
> 			java.util.Iterator itr = allBs.iterator();
> 
> 			assertEquals(allBs.size(), 1);
> 			System.out.println("testPathClassPerCriteria() iteration size:" + allBs.size());
> 			while (itr.hasNext())
> 			{
> 				B b = (B)itr.next();
> 				System.out.println("Found B:  " + b.getId() + " " + b.getBAttrib());
> 			}
> 		}
> 		catch (Throwable t)
> 		{
> 			t.printStackTrace(System.out);
> 			fail("testPathClassPerCriteria: " + t.getMessage());
> 		}
> 	}
> 	
> 
> }
> 
> 
> 
> 
> 
> ------------------------------------------------------------------------
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-dev-help@db.apache.org

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


Mime
View raw message