---
title: Retrieve business object from criteria
summary: Instantiates a business object from criteria and hydrates it through the retrieve lifecycle and active data portal.
status: draft
owner: SAIF
last_reviewed: 2026-07-30
library: SAIF.Framework.Core
reference_type: package
operation_id: OP-CORE-004
trigger: Caller invokes IDataAccess.RetrieveObject(criteria).
---

# Retrieve business object from criteria

This operation is the framework's retrieval pipeline for both SQL-backed and API-backed business objects. It instantiates the type associated with the criteria, runs the object's retrieve hooks, processes the resulting portal request unconditionally, and returns the fully hydrated object — unlike create, retrieve has no in-memory shortcut, since a retrieve without a data round-trip has nothing to hydrate from.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-CORE-004 |
| **Trigger** | Caller invokes `IDataAccess.RetrieveObject(criteria)`. |
| **Inputs** | `IBusinessCriteria` or `IBusinessApiCriteria` instance with a populated `DataPortalInfo`. |
| **Outputs** | Hydrated business object after `BeforeRetrieve`/`AfterRetrieve`. |
| **Primary components** | `clsDataAccess.RetrieveObject(IBusinessCriteria)`, `clsDataAccess.RetrieveObject(IBusinessApiCriteria)` |
| **Entry point** | `SAIF.Framework.Core\V1\DataAccessLayer\clsDataAccess.vb` |

## Steps

1. Validate that criteria were supplied.
   - If `inCriteria Is Nothing`, the method throws `SystemException`.
2. Determine the target type and instantiate the object.
   - The framework reads `inCriteria.GetType.DeclaringType`.
   - It creates the object instance with `Activator.CreateInstance(dataType, True)`, assigns `CriteriaObject`, and calls `OnInstantiation()`.
3. Prepare the retrieve portal request.
   - The framework resolves the portal from `busObj.CriteriaObject.DataPortalInfo.PortalID`.
   - It creates a new request with ID `Retrieve Request for <Type>`.
   - It calls `busObj.BeforeRetrieve(PortalRequest)` so the object can queue work for the retrieve phase.
4. Execute the retrieve batch.
   - The portal connects and processes the request batch.
   - `busObj.AfterRetrieve(PortalRequest)` hydrates the object from the returned data.
   - Any reader results are closed before the method leaves the `Try` block.
5. Finish the retrieve lifecycle.
   - The portal disconnects in `Finally`.
   - `OnInstantiationComplete()` runs after the `Try...Finally` block.
   - The hydrated object is returned to the caller.
6. Wrap any failure in a framework exception.
   - Exceptions are rethrown as `ApplicationException(MSG_DATA_RETRIEVE_EX & ex.Message, ex)`.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([RetrieveObject called]) --> Check{Criteria supplied?}
	Check -->|No| EndErr([Throw SystemException])
	Check -->|Yes| NewObj[Instantiate target object]
	NewObj --> Before[Run BeforeRetrieve]
	Before --> Portal[Connect portal and process request]
	Portal --> After[Run AfterRetrieve]
	After --> Done[Run OnInstantiationComplete]
	Done --> EndOk([Return hydrated object])
```

## Failure and edge-case behavior

- A missing criteria object is rejected with `SystemException` before any portal work begins.
- The retrieve path always runs `BeforeRetrieve` and processes a portal request — there is no direct `Create()`-style in-memory shortcut, so every retrieve is a data round-trip by design.
- Portal and hydration failures are wrapped in `ApplicationException(MSG_DATA_RETRIEVE_EX & ex.Message, ex)`, and the portal still disconnects in `Finally` even when `AfterRetrieve` throws.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- SAIF.Framework.Core\V1\DataAccessLayer\clsDataAccess.vb
