Skip to content

Identifiable, Named, and SearchableText

These three interfaces are the minimum contracts that entities and row DTOs must satisfy to work with Mateu’s CRUD orchestrators and listing components.


Every entity used with AutoCrud, AutoCrud, or any CrudStore must implement Identifiable.

public interface Identifiable {
String id();
}

Mateu uses id() to:

  • Link listing rows to their detail view.
  • Populate the URL parameter (:id) when navigating to view/edit screens.
  • Identify which records to delete when the user selects rows and clicks Delete.
public record Product(
String id,
String name,
BigDecimal price,
ProductStatus status
) implements Identifiable {}

For records, id() is already provided by the component accessor — no extra method needed.

public class Product implements Identifiable {
private String id;
private String name;
@Override
public String id() { return id; }
}

Row DTOs shown in a grid also benefit from Identifiable. Mark the id field with @PrimaryKey so Mateu knows which column to use as the row identifier:

public record ProductRow(
@PrimaryKey String id,
String name,
BigDecimal price
) implements Identifiable {}

Without @PrimaryKey, Mateu falls back to the field named id if it exists.


Named extends Identifiable and adds a name() method. Implement it when you want Mateu to display a human-readable title in the detail view header or in breadcrumbs — instead of falling back to toString().

public interface Named extends Identifiable {
String name();
}
public record Product(
String id,
String name,
BigDecimal price
) implements Named {
@Override
public String name() { return name; }
}

The CRUD detail pages use named.name() as the page title when the entity implements Named. If it does not, the title falls back to the standard title resolution (@Title, TitleSupplier, class name).

Named is also required by CompositionCrudStore — child entities used in embedded grids must implement Named.


SearchableText lets an entity control how it matches a free-text search in the auto adapters. (Not to be confused with the Searchable capability interface, which shows the search box on a listing.)

public interface SearchableText {
String searchableText();
}

AutoCrud<T> and FilteredAutoCrud<F,T> filter rows in memory using this priority:

  1. If T implements SearchableText → use searchableText().
  2. Otherwise → use toString().
public record Product(
String id,
String name,
String description,
BigDecimal price
) implements Identifiable, SearchableText {
@Override
public String searchableText() {
return name + " " + description;
}
}

This is only relevant when you rely on in-memory filtering. If you override CrudStore.find(...) to run a database query, SearchableText is not involved.


InterfaceRequired byPurpose
IdentifiableCrudStore<T>, AutoCrud<T>, FilteredAutoCrud<F,T>Identifies each entity so the framework can navigate, select, and delete rows
NamedCompositionCrudStore<T, P>, CRUD detail pages (optional)Provides a human-readable title for detail views and breadcrumbs
SearchableTextAutoCrud<T>, FilteredAutoCrud<F,T> (optional)Controls which text is matched during in-memory free-text search

  • AutoCrud<T> — where Identifiable and SearchableText are consumed
  • CrudStore — the repository that requires T extends Identifiable
  • AutoCrud — the orchestrators that put it all together