DAO Generator

Describe an item model and its finder methods -- get the DAO interface/impl, a service layer on top, and the Spring beans wiring it together.

🔒 Your code never leaves your browser — everything is generated locally from templates, no AI, no server round-trip.

  • Item model name is required.
  • Add at least one finder method.
The item type this DAO queries, e.g. LoyaltyAccount -- queries run against {LoyaltyAccount}.

Finder methods

trainingcore/src/com/prospect2p/core/daos/ItemDao.java
1
2
3
4
5
6
7
8
9
package com.prospect2p.core.daos;

import com.prospect2p.core.model.ItemModel;

public interface ItemDao
{
    // no finder methods configured yet
}
Generated scaffold. Review and test before using in production.
Advertisement

What is a DAO in SAP Commerce?

A DAO (Data Access Object) in SAP Commerce (Hybris) is the layer that talks FlexibleSearch so the rest of the codebase doesn't have to -- a small interface plus a Default*Dao implementation backed by FlexibleSearchService, each finder method building a parameterized query and returning model objects (never raw ResultSet rows).

Convention is to never expose the DAO directly to facades/controllers -- a thin service interface/implementation sits on top, delegating to the DAO, so business logic has one stable seam even if the query layer changes underneath it.

When to use it

Use a custom DAO whenever you need to look up model instances by anything beyond what DefaultGenericDao's generic find-by-example already covers -- a specific WHERE clause, an ORDER BY, pagination, or a join across relations.

If a lookup is truly a plain "find all X where attribute = value" with no special ordering or paging, DefaultGenericDao (or Spring's findValues with a PK) may already do the job without a custom class at all.

Files generated

  • The DAO interface (<Item>Dao.java) declaring one method per configured finder.
  • The DAO implementation (Default<Item>Dao.java), built on FlexibleSearchService with named query parameters.
  • A service interface and implementation that delegate to the DAO -- the layer the rest of the codebase should actually call.
  • A Spring bean wiring the DAO impl (and PaginatedFlexibleSearchService, if any finder is paginated) plus the service impl.

Step-by-step: how to use the output

  1. Copy the DAO interface and impl into <extension>/src/<package>/daos/ and daos/impl/, and the service interface/impl into services/ and services/impl/.
  2. Merge the generated Spring beans into your extension's -spring.xml.
  3. Inject the service bean id (not the DAO bean id) wherever the finder is needed -- facades, controllers, populators -- keeping the DAO as an internal implementation detail.
  4. Write a unit/integration test per finder method, asserting against known seeded data, before relying on it in a facade.

Common mistakes

  • Building the FlexibleSearch WHERE clause by string-concatenating a search value instead of using addQueryParameter() -- besides being fragile with quoting, it reintroduces the class of injection risk named parameters exist to avoid.
  • Calling the DAO directly from a facade or controller instead of going through the service layer -- it works today, but removes the one seam that lets the query implementation change later without touching callers.
  • Forgetting ORDER BY on a method that returns a List -- without it, result order is whatever the database happens to return, which can silently change between runs.
  • Using plain (unpaginated) FlexibleSearchService.search() for a listing endpoint that could return thousands of rows -- reach for PaginatedFlexibleSearchService instead so the query doesn't load everything into memory at once.

Frequently asked questions

FlexibleSearchService vs DefaultGenericDao -- which should I use?

DefaultGenericDao's findByExample-style lookups cover simple equality searches with no custom logic. Reach for a FlexibleSearchService-backed DAO (what this generator produces) as soon as you need a specific WHERE/ORDER BY, a join, or pagination -- anything DefaultGenericDao's generic API can't express.

Why named query parameters instead of building the query string with the values in it?

addQueryParameter("customer", customer) lets FlexibleSearchQuery handle type conversion and escaping for you -- string-concatenating a value into the query text is fragile (quoting, type formatting) and reopens a class of injection risk the parameterized API exists specifically to close.

How does pagination work here?

A paginated finder takes a PageableData parameter and calls PaginatedFlexibleSearchService.search(query, pageableData) instead of the plain FlexibleSearchService, returning a SearchResult<T> that carries both the page of results and paging metadata (total count, page size).

Why put a service layer on top of the DAO instead of calling it directly?

The service interface is the stable contract the rest of the app depends on. If the underlying query implementation ever needs to change -- a different index, a caching layer, a completely different data source -- only the service impl changes; every facade/controller that depends on the service interface is unaffected.

How do I test a DAO?

Use an integration test extending ServicelayerTransactionalTest (or the project's equivalent base class) that imports known ImpEx test data, then asserts the finder returns exactly the expected rows -- a DAO test is one of the few places hitting the real database is the right call, since the whole point is verifying the FlexibleSearch query itself.

🗳️ Vote for the next SAP Commerce guide

Vote or suggest a topic
What should we write next? Vote