Customising AutoCrud behaviour
AutoCrud<T> and FilteredAutoCrud<Filters, T> cover the common case out of the box. When you need to go further — custom search queries, pre-populated creation forms, or a custom read-only view — override the protected hooks directly in your subclass. No extra class is needed.
Override points in FilteredAutoCrud
Section titled “Override points in FilteredAutoCrud”These methods are public in FilteredAutoCrud and can be overridden in any AutoCrud or FilteredAutoCrud subclass:
| Method | Default behaviour | Override to… |
|---|---|---|
fetchRows(searchText, filters, pageable, httpRequest) | In-memory filter via toString() / Searchable.searchableText() | Query a database or external service |
buildNamedView(id, httpRequest) | Loads via repository().findById(id), wraps in AutoNamedView | Return a custom view (pre-loaded data, extra context, etc.) |
buildCreationForm(httpRequest) | Instantiates a new T, wraps in AutoNamedView | Pre-populate fields on the creation form |
Example — custom search
Section titled “Example — custom search”@Service@UI("/products")public class ProductCrud extends FilteredAutoCrud<ProductFilters, Product> {
private final ProductRepository repository;
public ProductCrud(ProductRepository repository) { this.repository = repository; }
@Override public Class filtersClass() { return ProductFilters.class; }
@Override public CrudRepository<Product> repository() { return repository; }
@Override public ListingData<Product> fetchRows( String searchText, ProductFilters filters, Pageable pageable, HttpRequest httpRequest) { return repository.search(searchText, filters.category(), filters.active(), pageable); }}Example — pre-populated creation form
Section titled “Example — pre-populated creation form”@Service@UI("/orders")public class OrderCrud extends AutoCrud<Order> {
private final OrderRepository repository;
public OrderCrud(OrderRepository repository) { this.repository = repository; }
@Override public CrudRepository<Order> repository() { return repository; }
@Override public AutoNamedView<Order> buildCreationForm(HttpRequest httpRequest) { var order = new Order(); order.setDate(LocalDate.now()); order.setStatus(OrderStatus.DRAFT); return new AutoNamedView<>(Order.class, order, repository()); }}AutoNamedView
Section titled “AutoNamedView”AutoNamedView<T> is what buildNamedView and buildCreationForm return by default. It wraps any T extends Identifiable and wires all CRUD contracts to the entity and the repository:
new AutoNamedView<>(entityClass, entity, repository)| Constructor parameter | Purpose |
|---|---|
entityClass | Determines which fields to render |
entity | The object serialised as form state |
repository | Called by save() and create() to persist |
When these hooks are not enough
Section titled “When these hooks are not enough”If the view, editor, and creation form need to be genuinely different types (different fields, different DTOs), step up to Crud<View,Editor,CreationForm,Filters,Row,Id> and implement CrudAdapter directly.
- FilteredAutoCrud — add a dedicated filter model
- CrudAdapter — the interface for a fully custom data layer
- CrudRepository — the repository contract these hooks delegate to