Skip to content

FilteredAutoCrud

AutoCrud<T> uses the same type T for everything — including the filter bar. This works when the entity fields are a reasonable filter form, but breaks down when you need:

  • A dedicated filter DTO with fewer or different fields.
  • Computed or derived filter parameters that don’t exist on the entity.
  • A clean separation between what the grid shows and what the filter bar exposes.

FilteredAutoCrud<Filters, T> adds a separate Filters type while keeping the simplicity of AutoCrud.


Separate filter and entity types. Everything else — view, edit form, creation form, and row — still uses T.

public abstract class FilteredAutoCrud<Filters, T extends Identifiable>
extends Crud<AutoNamedView<T>, AutoNamedView<T>, AutoNamedView<T>, Filters, T, String>

Override filtersClass() to tell Mateu which class to use for the filter bar, provide a repository() for save/delete/view operations, and override fetchRows() to apply the custom filters:

@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);
}
}
public record ProductFilters(
String category,
boolean active
) {}
public record Product(
@EditableOnlyWhenCreating String id,
@NotEmpty String name,
String category,
boolean active,
BigDecimal price
) implements Identifiable {}

Add @ReadOnly (and optionally @NotNavigable) to make the listing read-only:

@Service
@UI("/audit-log")
@ReadOnly
public class AuditLog extends FilteredAutoCrud<AuditFilters, AuditEntry> {
private final AuditRepository repository;
public AuditLog(AuditRepository repository) { this.repository = repository; }
@Override
public Class filtersClass() { return AuditFilters.class; }
@Override
public CrudRepository<AuditEntry> repository() { return repository; }
}

ClassFilter typeRow typeWrite operations
AutoCrud<T>TT✓ (or @ReadOnly)
FilteredAutoCrud<Filters,T>FiltersT✓ (or @ReadOnly)
Crud<V,E,C,F,R,Id>FR✓ (or @ReadOnly, full control)

Use FilteredAutoCrud when:

  • The entity itself is the right form for view, edit, and create.
  • You need a dedicated filter model (separate DTO with different fields).
  • You don’t need separate view/editor/creation form types (use Crud for that).