AutoCrud<T>
AutoCrud<T> uses a single type parameter T for filters, rows, view, and edit forms. It is the fastest way to get a working CRUD on screen. Capability annotations let you strip write operations one by one — turning the same class into a listing, a read-only catalogue, or any combination in between.
Class signature
Section titled “Class signature”public abstract class AutoCrud<T extends Identifiable> extends FilteredAutoCrud<T, T>Methods to implement
Section titled “Methods to implement”| Method | Purpose |
|---|---|
repository() | Return the CrudRepository<T> used for all operations |
Minimal example — full CRUD
Section titled “Minimal example — full CRUD”@Service@UI("/products")public class ProductCrud extends AutoCrud<Product> {
private final ProductRepository repository;
public ProductCrud(ProductRepository repository) { this.repository = repository; }
@Override public CrudRepository<Product> repository() { return repository; }}public record Product( @EditableOnlyWhenCreating @NotEmpty String id, @NotEmpty String name, BigDecimal price, ProductStatus status) implements Identifiable {}This gives you:
| Route | Screen |
|---|---|
/products | Listing with New and Delete buttons |
/products/:id | Read-only detail view with Edit button |
/products/:id/edit | Edit form |
/products/new | Create form |
Controlling capabilities with annotations
Section titled “Controlling capabilities with annotations”Add any combination of these class-level annotations to restrict what users can do:
| Annotation | Effect |
|---|---|
@ReadOnly | Shorthand for @NotCreatable @NotEditable @NotDeletable |
@NotCreatable | Hides the New button in the list |
@NotEditable | Hides the Edit button in the detail view |
@NotDeletable | Hides the Delete button in the list |
@NotNavigable | Hides the View button column — rows are not clickable |
These combine freely. A few common patterns:
| Intent | Annotations |
|---|---|
| Full CRUD | (nothing) |
| Read-only with detail view | @ReadOnly |
| Simple read-only list (no detail) | @ReadOnly @NotNavigable |
| List you can add to, but not click into | @NotNavigable |
| List you can edit but not create | @NotCreatable |
| List you can edit but not delete | @NotDeletable |
Read-only listing example
Section titled “Read-only listing example”@Service@UI("/audit-log")@ReadOnly@NotNavigablepublic class AuditLog extends AutoCrud<AuditEntry> {
private final AuditRepository repository;
public AuditLog(AuditRepository repository) { this.repository = repository; }
@Override public CrudRepository<AuditEntry> repository() { return repository; }}The write operations are simply never invoked for a read-only AutoCrud.
What AutoCrud provides out of the box
Section titled “What AutoCrud provides out of the box”| Operation | Behaviour |
|---|---|
search | Delegates to repository().find(searchText, filters, pageable) → Page<T> (default: filters by Searchable.searchableText()/toString(), sorts by pageable.sort(), paginates in memory) |
getView | Loads entity by id and wraps in AutoNamedView |
getEditor | Same as view — entity fields become editable inputs |
getCreationForm | Instantiates a new T and wraps in AutoNamedView |
deleteAllById | Delegates to repository().deleteAllById() |
For most use cases repository() is the only method you need to implement. To push search, filtering, sorting and pagination to the database, override CrudRepository.find(...) — AutoCrud calls it automatically. To customise other operations (pre-populated creation forms, etc.) override the protected hooks fetchRows(), buildNamedView(), or buildCreationForm() directly in your subclass — see Customising AutoCrud behaviour.
Limitations of the single-type approach
Section titled “Limitations of the single-type approach”AutoCrud<T> uses T for every screen, which means:
- The filter bar shows the same fields as the grid rows.
- The edit form shows the same fields as the detail view.
- The create form is identical to the edit form.
When this is too restrictive, move to:
FilteredAutoCrud<Filters, T>— separate filter type, same entity for everything else.Crud<View,Editor,CreationForm,Filters,Row,Id>— full control over every screen.
- Customizing CRUD and listings — annotations and layout adjustments before overriding hooks
- Filtered orchestrators — add a dedicated filter model without leaving the auto variants
- Full control with Crud — when each screen needs a separate model
- EditableView — single-entity view with an Edit button, no list