# Jmix Framework Documentation Jmix is a high-level full-stack framework for building enterprise web applications in Java. It provides a comprehensive set of tools for data modeling, data access, security, UI development, and REST API generation. Built on top of Spring Boot, Jmix offers a rapid application development experience with features like automatic CRUD operations, entity management, role-based security, and a rich component library based on Vaadin Flow. The framework supports JPA entities with automatic database migrations, a powerful DataManager for CRUD operations, declarative security with resource and row-level roles, and a modern reactive UI using Flow components. Jmix also provides a Generic REST API add-on that automatically exposes endpoints for entity operations, business services, and file management without writing custom REST controllers. ## DataManager - Loading Entities DataManager is the main interface for CRUD operations on entities, providing a fluent API for loading, saving, and removing data with automatic security checks and transaction management. ```java @Component public class CustomerService { @Autowired private DataManager dataManager; // Load entity by ID Customer loadById(UUID customerId) { return dataManager.load(Customer.class) .id(customerId) .one(); } // Load with optional result (returns empty if not found) Customer loadOrCreate(UUID customerId) { return dataManager.load(Customer.class) .id(customerId) .optional() .orElse(dataManager.create(Customer.class)); } // Load all entities (use with caution for large datasets) List loadAll() { return dataManager.load(Customer.class).all().list(); } // Load by JPQL query with parameters List loadByQuery() { return dataManager.load(Customer.class) .query("select c from sample_Customer c where c.email like :email and c.grade = :grade") .parameter("email", "%@company.com") .parameter("grade", CustomerGrade.PLATINUM) .list(); } // Abbreviated query syntax with positional parameters List loadByQueryShort() { return dataManager.load(Customer.class) .query("e.email like ?1 and e.grade = ?2", "%@company.com", CustomerGrade.PLATINUM) .list(); } // Load using property conditions List loadByConditions() { return dataManager.load(Customer.class) .condition( LogicalCondition.and( PropertyCondition.contains("email", "@company.com"), PropertyCondition.equal("grade", CustomerGrade.PLATINUM) ) ) .list(); } // Paging and sorting List loadPageSorted(int offset, int limit) { return dataManager.load(Customer.class) .query("e.grade = ?1", CustomerGrade.BRONZE) .firstResult(offset) .maxResults(limit) .sort(Sort.by("name")) .list(); } } ``` ## DataManager - Saving and Removing Entities DataManager provides methods for persisting new entities, updating existing ones, and removing entities from the database with proper transaction handling. ```java @Component public class OrderService { @Autowired private DataManager dataManager; // Save a single entity Customer saveCustomer(Customer entity) { return dataManager.save(entity); } // Save without reload for better performance void saveCustomerWithoutReload(Customer entity) { dataManager.saveWithoutReload(entity); } // Create and save multiple linked entities Order createOrderWithCustomer() { Customer customer = dataManager.create(Customer.class); customer.setName("Alice"); Order order = dataManager.create(Order.class); order.setCustomer(customer); EntitySet savedEntities = dataManager.save(order, customer); return savedEntities.get(order); } // Save a collection of entities EntitySet saveCustomers(List entities) { return dataManager.saveAll(entities); } // Batch save for large collections (performance optimization) void saveInBatches(List entities) { for (int i = 0; i < entities.size(); i += 100) { int endIndex = Math.min(i + 100, entities.size()); List batch = entities.subList(i, endIndex); dataManager.saveWithoutReload(batch); } } // Remove entity void removeCustomer(Customer entity) { dataManager.remove(entity); } // Remove by ID void removeCustomerById(UUID customerId) { dataManager.remove(Id.of(customerId, Customer.class)); } // Hard delete (bypassing soft deletion) void hardDelete(Product product) { dataManager.save( new SaveContext() .removing(product) .setHint(PersistenceHints.SOFT_DELETION, false) ); } // Bypass security checks with UnconstrainedDataManager @Autowired private UnconstrainedDataManager unconstrainedDataManager; Customer loadByIdUnconstrained(UUID customerId) { return unconstrainedDataManager.load(Customer.class) .id(customerId) .one(); } } ``` ## JPA Entity Definition JPA entities in Jmix are standard JPA entities with additional Jmix-specific annotations for enhanced functionality like automatic ID generation, instance naming, and entity traits. ```java @JmixEntity @Table(name = "CUSTOMER") @Entity public class Customer { @JmixGeneratedValue @Id @Column(name = "ID", nullable = false) private UUID id; @Version @Column(name = "VERSION") private Integer version; @InstanceName @NotNull @Column(name = "NAME", nullable = false) private String name; @Email @Column(name = "EMAIL", unique = true) private String email; // Audit traits @CreatedBy @Column(name = "CREATED_BY") private String createdBy; @CreatedDate @Column(name = "CREATED_DATE") private OffsetDateTime createdDate; @LastModifiedBy @Column(name = "LAST_MODIFIED_BY") private String lastModifiedBy; @LastModifiedDate @Column(name = "LAST_MODIFIED_DATE") private OffsetDateTime lastModifiedDate; // Soft delete traits @DeletedBy @Column(name = "DELETED_BY") private String deletedBy; @DeletedDate @Column(name = "DELETED_DATE") private OffsetDateTime deletedDate; // Many-to-One relationship @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "DEPARTMENT_ID") private Department department; // One-to-Many composition @OrderBy("rowNum") @Composition @OneToMany(mappedBy = "customer") private List orders; public UUID getId() { return id; } public void setId(UUID id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } // Other getters and setters... } ``` ## DataGrid Component DataGrid displays tabular data with support for sorting, filtering, inline editing, and lazy loading for efficient handling of large datasets. ```xml ``` ```java // View controller @ViewController("orders-list") @ViewDescriptor("orders-list.xml") public class OrdersListView extends StandardView { @ViewComponent private DataGrid ordersGrid; @ViewComponent private CollectionContainer ordersDc; @Subscribe public void onInit(InitEvent event) { // Programmatic column configuration ordersGrid.getAllColumns().forEach(col -> col.setSortable(true)); ordersGrid.setColumnReorderingAllowed(true); } // Custom renderer for a column @Supply(to = "ordersGrid.status", subject = "renderer") private Renderer ordersGridStatusRenderer() { return new TextRenderer<>(order -> order.isOverdue() ? "Overdue!" : "On Track"); } // Inline editing with auto-save @Install(to = "ordersGrid.@editor", subject = "closeListener") private void ordersGridEditorCloseListener(EditorCloseEvent event) { Order order = event.getItem(); Order savedOrder = dataManager.save(order); ordersDc.replaceItem(savedOrder); } } ``` ## Button Component and Event Handling Buttons trigger actions in response to user clicks and can display text, icons, or both with various styling options. ```xml