Guide‎ > ‎Logic Design Patterns‎ > ‎

Find Where


Constraints often require matching rows exist / do not exist in other collections.  See the examples below.

Solution: provide re-usable Logic

Since this is a common pattern, we provide a re-usable Java class with:


com.autobizlogic.abl.businesslogic.FindWhere.findFirst(LogicContext aLogicContext, Set<?> aSet, String aFilter)


aLogicContext identifies the current source row, as described below

aSet e.g., productBillofmaterials.getProduct().getComponents()

aFilter e.g., =


matching row, or null

This service is typically called from a constraint.  A similar method FindFirst ensures that only one matching row exists (else throws an Exception).


The following examples illustrate Find Where.

LanguageSpoken exists for each LanguageTranslated

Thanks to Florian of MinuteProject for this clear example: imagine a Person had 2 n:m relationships to Language: LanguageSpoken and LanguageTranslates.  It is a certain requirement that a person must speak a language in order to translate it.  So, we can use FindWhere to verify a Person has a LanguageSpoken for each LanguageTranslates.

Component may not be a containing kit

With a Bill of Materials structure, we want to ensure that a component is not a containing kit.  We can enforce this with the following constraint:

The key system capability is that Constraint methods can invoke Java methods, such as FindWhere.  The invocation at line 73 passes the sub-components of our component, searching for sub-component where the equals our source kit name.

The BusLogicIntro samples provide a jUnit test of this service.  As shown below, we attempt to add a plane as a component of a Wing, and then verify that the expected constraint exception was raised:

FindWhere Operation

FindWhere operates by iterating though the collection, evaluating the filter condition via jexl.  This makes effective use of the Hibernate cache, but is not suitable for large collections.

@source reference

The filter passed to FindWhere is evaluated for each row in aSet.  By default, the operands are properties of this domain object.

In most cases, you need to compare these to some property in the source domain object (i.e., the @CurrentBean where you defined the Constraint).  You can reference these attributes using the @source reference as illustrated above.  The actual bean instance is obtained from the logicContext passed to FindWhere.