Model linking provides the mechanism for establishing master-detail relationships between entity models. The framework automatically synchronizes detail models based on master model selection and data changes.
1. Overview
The ModelLink API enables automatic detail model filtering based on master selection and propagation of data changes.
// Invoice -> InvoiceLines
SwingEntityModel invoiceModel = new SwingEntityModel(Invoice.TYPE, connectionProvider);
SwingEntityModel invoiceLineModel = new SwingEntityModel(InvoiceLine.TYPE, connectionProvider);
invoiceModel.detailModels().add(invoiceLineModel);
// Configure detail model for optimal performance
invoiceLineModel.tableModel().queryModel().conditionRequired().set(true); // Don't load all lines
invoiceLineModel.tableModel().queryModel().limit().set(1000); // Reasonable limit
2. Building Custom Links
Create links with specific behavior:
SwingEntityModel customerModel = new SwingEntityModel(Customer.TYPE, connectionProvider);
SwingEntityModel invoiceModel = new SwingEntityModel(Invoice.TYPE, connectionProvider);
ModelLink<SwingEntityModel, SwingEntityEditModel, SwingEntityTableModel> customLink =
customerModel.link(invoiceModel)
.active(true)
.onSelection(selectedCustomers -> {
// Custom selection logic
if (selectedCustomers.size() > 1) {
// Handle multi-selection differently
invoiceModel.tableModel().queryModel().condition().clear();
invoiceModel.tableModel().queryModel().where().set(() ->
Invoice.CUSTOMER_FK.in(selectedCustomers)
);
}
})
.build();
customerModel.detailModels().add(customLink);
3. Automatic Foreign Key Management
The ForeignKeyModelLink specializes ModelLink
for foreign key relationships:
SwingEntityModel customerModel = new SwingEntityModel(Customer.TYPE, connectionProvider);
SwingEntityModel invoiceModel = new SwingEntityModel(Invoice.TYPE, connectionProvider);
// ForeignKeyModelLink is created automatically when foreign key is detected
customerModel.detailModels().add(invoiceModel);
// Or configure explicitly
customerModel.detailModels().add(ForeignKeyModelLink.builder(invoiceModel, Invoice.CUSTOMER_FK)
// Clear foreign key value when master has no selection
.clearValueOnEmptySelection(true)
// Set foreign key value automatically on insert
.setValueOnInsert(true)
// Control when to refresh detail data
.refreshOnSelection(true)
// Filter detail records based on master selection
.setConditionOnInsert(true)
.build());
4. Simple One-to-Many
Classic master-detail relationship:
// Invoice -> InvoiceLines
SwingEntityModel invoiceModel = new SwingEntityModel(Invoice.TYPE, connectionProvider);
SwingEntityModel invoiceLineModel = new SwingEntityModel(InvoiceLine.TYPE, connectionProvider);
invoiceModel.detailModels().add(invoiceLineModel);
// Configure detail model for optimal performance
invoiceLineModel.tableModel().queryModel().conditionRequired().set(true); // Don't load all lines
invoiceLineModel.tableModel().queryModel().limit().set(1000); // Reasonable limit
5. Multi-Level Hierarchy
Deep master-detail chains:
// Customer -> Invoice -> InvoiceLine
SwingEntityModel customerModel = new SwingEntityModel(Customer.TYPE, connectionProvider);
SwingEntityModel invoiceModel = new SwingEntityModel(Invoice.TYPE, connectionProvider);
SwingEntityModel invoiceLineModel = new SwingEntityModel(InvoiceLine.TYPE, connectionProvider);
// Build hierarchy
customerModel.detailModels().add(invoiceModel);
invoiceModel.detailModels().add(invoiceLineModel);
// Configure each level
invoiceModel.tableModel().queryModel().conditionRequired().set(true);
invoiceLineModel.tableModel().queryModel().conditionRequired().set(true);
// Selection cascades down the hierarchy automatically
Entity customer = getCustomer(connectionProvider);
customerModel.tableModel().selection().item().set(customer);
// Invoices for customer are loaded
// When an invoice is selected, its lines are loaded
invoiceModel.tableModel().selection().indexes().increment();// selects first