Appearance
@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:
- Create a repository with query, export, and audit support
- Create a service with CRUD operations and event publishing
- 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 { /* ... */ }menuOrder
Controls the position of the entity in the navigation menu. Lower values appear first:
java
@SquizyEntity(menuOrder = 1)
@Entity
public class Product { /* ... */ }menuPlacement
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:
| Method | Description | Default |
|---|---|---|
name() | Category identifier | Class name without Category suffix |
label() | Display label (supports i18n with {key} syntax) | null (uses name()) |
icon() | CSS icon class | "" |
section() | Menu section grouping | DefaultSection.class |
isCollapsable() | Whether the category can be collapsed | true |
isExpandedByDefault() | Whether it starts expanded | false |
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
}