Skip to content

@SquizyEntity

The @SquizyEntity annotation is the core building block of any Squizy application. It marks a JPA @Entity class as a Squizy-managed entity, which triggers the automatic generation of a full CRUD stack: repository, service, and REST controller.

Basic Usage

java
@Entity
@SquizyEntity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    @Size(max = 50)
    private String name;

    @NotNull
    private BigDecimal price;

    // getters and setters
}

Just by adding @SquizyEntity, the framework will:

  1. Create a repository with query, export, and audit support
  2. Create a service with CRUD operations and event publishing
  3. Register REST endpoints (GET, POST, PATCH, DELETE) under /api/{entity-name}

Attributes

displayFormat

Defines how the entity is represented as text when displayed in relationships, dropdowns, tables, and search results. Uses ${fieldName} placeholders that reference entity fields:

java
@SquizyEntity(displayFormat = "${reference} - ${name}")
@Entity
public class Product {
    private String reference;
    private String name;
    // ...
}

You can reference nested fields for related entities:

java
@SquizyEntity(displayFormat = "${address}, ${city.name}")
@Entity
public class Address {
    private String address;
    @ManyToOne
    private City city;
    // ...
}

If displayFormat is not specified, the framework will guess a display format based on the entity's ID fields. See Display Format Guessing for details.

This attribute is an alias for the standalone @DisplayFormat annotation. At the field level, you can override the display format for a specific relationship using @SquizyField(displayFormat = ...) or @DisplayFormat on the field.

sortingExpression

Defines the default sorting order for the entity across all queries — including dropdowns, relationship lists, and table views (unless overridden by defaultTableSortingExpression). Uses the same ${fieldName} placeholder syntax as displayFormat:

java
@SquizyEntity(sortingExpression = "${name}")
@Entity
public class Category { /* ... */ }

ID is always appended as last sort criterion

To guarantee deterministic ordering for pagination and streaming, the entity's ID field is always appended as the final sorting criterion. This ensures that records with identical sorting values are returned in a stable, reproducible order.

This attribute is an alias for the standalone @SortingExpression annotation. At the field level, you can override the sorting expression for a specific relationship using @SquizyField(sortingExpression = ...) or @SortingExpression on the field.

defaultTableSortingExpression

Overrides the sorting order specifically for the entity's table view, while sortingExpression continues to apply in all other contexts (dropdowns, relationship lists, etc.). When not set, it falls back to the value of sortingExpression.

This is useful when you want a different default order in the table view compared to how items appear in dropdowns or relationships:

java
@SquizyEntity(
    sortingExpression = "${name}",
    defaultTableSortingExpression = "${createdDate}"
)
@Entity
public class Product { /* ... */ }

In this example, products appear sorted by name in dropdowns, but by creation date in the table view.

This attribute is an alias for the standalone @DefaultTableSortingExpression annotation.

icon

Specifies a CSS icon class (e.g., FontAwesome) for the entity in the navigation menu:

java
@SquizyEntity(icon = "fas fa-box")
@Entity
public class Product { /* ... */ }

Controls the position of the entity in the navigation menu. Lower values appear first:

java
@SquizyEntity(menuOrder = 1)
@Entity
public class Product { /* ... */ }

Groups entities under a menu category. Entities with the same MenuPlacement class are grouped together in the sidebar:

java
// Define a category
public class OrdersCategory implements MenuCategory {
    @Override
    public String name() {
        return "orders";
    }

    @Override
    public String icon() {
        return "fas fa-box-open";
    }
}

// Assign entities to the category
@SquizyEntity(menuPlacement = OrdersCategory.class)
@Entity
public class Product { /* ... */ }

@SquizyEntity(menuPlacement = OrdersCategory.class)
@Entity
public class Order { /* ... */ }

The MenuCategory interface supports additional customization:

MethodDescriptionDefault
name()Category identifierClass name without Category suffix
label()Display label (supports i18n with {key} syntax)null (uses name())
icon()CSS icon class""
section()Menu section groupingDefaultSection.class
isCollapsable()Whether the category can be collapsedtrue
isExpandedByDefault()Whether it starts expandedfalse

compositeIdSeparator

Defines the URL separator for composite keys. Defaults to ___ (configured globally via squizy.server.default-composite-id-separator):

java
@SquizyEntity(compositeIdSeparator = "--")
@Entity
public class BookAuthor {
    @EmbeddedId
    private BookAuthorId id;
    // ...
}

hidden

Hides the entity from the navigation menu. Useful for supporting entities that are managed through relationships (e.g., order lines, addresses):

java
@SquizyEntity(hidden = true)
@Entity
public class OrderLine { /* ... */ }

INFO

Hidden entities still have full REST API endpoints. They are only hidden from the UI menu.

readOnly

Makes the entity read-only in the UI. No create, update, or delete operations will be available:

java
@SquizyEntity(hidden = true, readOnly = true)
@Entity
public class Country { /* ... */ }

skipLayersAutoGeneration

Disables automatic generation of repository, service, and controller layers. Use this when you need to provide fully custom implementations:

java
@SquizyEntity(skipLayersAutoGeneration = true)
@Entity
public class CustomProduct { /* ... */ }

Complete Example

Here's a real-world entity from the demo application that uses multiple attributes:

java
@DefaultView
@Audited
@SquizyEntity(displayFormat = "${reference} - ${name}", menuPlacement = OrdersCategory.class)
@Entity
public class Product {

    @Id
    @NotNull
    @Size(max = 50)
    private String reference;

    @SquizyField(bulkUpdatable = false)
    @NotNull
    @Size(max = 50)
    private String name;

    @NotNull
    private BigDecimal price;

    @ManyToOne(optional = false)
    @NotNull
    private Category category;

    @Enumerated(EnumType.STRING)
    @NotNull
    private Status status;

    @Size(max = 1500)
    private String description;

    // getters and setters
}