Здравствуйте! Версия 2.4.1, Idea 2024.3.
В продолжении с чата, повторюсь что при повторной вставке элементов в контейнер канбана не отображаются итемы.
Код KanbanEntity:
Спойлер
@JmixEntity
@Table(name = "KANBAN_ENTITY", indexes = {
@Index(name = "IDX_KANBAN_ENTITY_SUGGESTION", columnList = "SUGGESTION_ID")
})
@Entity
public class KanbanEntity {
@JmixGeneratedValue
@Column(name = "ID", nullable = false)
@Id
private UUID id;
@Column(name = "TEXT", nullable = false, length = 50)
@NotNull
private String text;
@Column(name = "STATUS", nullable = false, length = 100)
@NotNull
private String status;
@Column(name = "CREATION_DATE")
private LocalDate creationDate;
@Column(name = "DEPARTMENT_NUMBER", length = 50)
private String departmentNumber;
@OnDeleteInverse(DeletePolicy.CASCADE)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "SUGGESTION_ID")
private Suggestion suggestion;
Код класса экрана для отображения kanban (лишнее убрал).
Спойлер
public class KanbanListView extends StandardView {
@Autowired
private KanbanService kanbanService;
@ViewComponent
private CollectionContainer<KanbanEntity> kanbanEntitiesDc;
@ViewComponent
private TypedDatePicker<Comparable> startDate;
@ViewComponent
private TypedDatePicker<Comparable> endDate;
@ViewComponent
private TypedTextField<Object> departmentNumberField;
@ViewComponent
private Kanban<KanbanEntity> kanban;
@Subscribe
public void onInit(final InitEvent event) {
kanbanEntitiesDc.setItems(kanbanService.createAndGetCurrentSuggestionByKanban(
null, null, null));
kanban.getI18n().withEmpty("Нет предложений");
}
@Subscribe(id = "approveButton", subject = "clickListener")
public void onApproveButtonClick(final ClickEvent<JmixButton> event) {
kanbanEntitiesDc.setItems(kanbanService.createAndGetCurrentSuggestionByKanban(
startDate.getValue(),
endDate.getValue(),
departmentNumberField.getValue()));
}
@Subscribe(id = "resetButton", subject = "clickListener")
public void onResetButtonClick(final ClickEvent<JmixButton> event) {
startDate.setValue(null);
endDate.setValue(null);
departmentNumberField.setValue("");
kanbanEntitiesDc.setItems(kanbanService.createAndGetCurrentSuggestionByKanban(
startDate.getValue(),
endDate.getValue(),
departmentNumberField.getValue()));
}
Имплементация KanbanService (лишнее удалил):
Спойлер
@Component
public class KanbanServiceImpl implements KanbanService {
@Autowired
private UnconstrainedDataManager dataManager;
@Autowired
private StatisticService statisticService;
@Autowired
private FetchPlans fetchPlans;
private Map<UUID, KanbanEntity> kanbanCache = new ConcurrentHashMap<>();
@PostConstruct
private void buildKanbanCache() {
List<KanbanEntity> kanbans = dataManager.load(KanbanEntity.class)
.all().list();
kanbans.forEach(dataManager::remove);
List<Suggestion> suggestions = dataManager.load(Suggestion.class)
.all()
.fetchPlan(fetchPlans.builder(Suggestion.class)
.addAll("creationDate", "number", "status", "creatorDepartmentNumber", "id")
.build())
.list();
kanbans.clear();
for (Suggestion suggestion : suggestions) {
KanbanEntity kanbanEntity = dataManager.create(KanbanEntity.class);
kanbanEntity.setStatus(suggestion.getStatus());
kanbanEntity.setText(suggestion.getNumber());
kanbanEntity.setSuggestion(suggestion);
kanbanEntity.setDepartmentNumber(suggestion.getCreatorDepartmentNumber());
kanbanEntity.setCreationDate(suggestion.getCreationDate());
kanbans.add(kanbanEntity);
}
SaveContext saveContext = new SaveContext();
saveContext.saving(kanbans);
EntitySet entitySet = dataManager.save(saveContext);
entitySet.getAll(KanbanEntity.class)
.forEach(x -> kanbanCache.put(x.getSuggestion().getId(), x));
}
@Override
public List<KanbanEntity> createAndGetCurrentSuggestionByKanban(LocalDate startDate,
LocalDate endDate,
String departmentNumber) {
if (startDate == null) {
startDate = statisticService.getMinSuggestionDate();
}
if (endDate == null) {
endDate = LocalDate.now().plusDays(1);
}
LocalDate finalStartDate = startDate;
LocalDate finalEndDate = endDate;
Comparator<KanbanEntity> comparator = (x1, x2) -> x2.getCreationDate().compareTo(x1.getCreationDate());
return kanbanCache.values()
.stream()
.filter(x -> (x.getCreationDate().isAfter(finalStartDate)
&& x.getCreationDate().isBefore(finalEndDate)))
.filter(x -> (!StringUtils.hasText(departmentNumber)
|| x.getDepartmentNumber().equalsIgnoreCase(departmentNumber)))
.sorted(comparator)
.toList();
}
По коду наверное ± понятно что происходит, но на всякий по шагам.
- Приложение стартует, отрабатывает аннотация и метод
void buildKanbanCache()
сервисаKanbanServiceImpl
, который удаляет из базы всеKanbanEntity
и создаёт новые на основе имеющихся сущностейSuggestion
и кладёт их в базу и вMap<UUID, KanbanEntity> kanbanCache
(UUID это idSuggestion
, заготовка под обновление кэша при создании/измении главной сущности). - При открытии экрана в init-методе вызывается метод сервиса
createAndGetCurrentSuggestionByKanban(null, null, null)
, который отдаёт коллекцию, коллекция помещается в контейнер и экран открывается. На этом этапе отображается полный список всех имеющихсяkanbanEntity
. - Далее если выбрать какое-либо значение в полях экрана (текстовое или дату) и нажать кнопку “Подтвердить”, то данные записываются в поля в java-классе и вызывается сервис с данными из этих полей. Например выбираю дату “с” 01.11.2024 и нажимаю принять. Сервис отрабатывает и возвращает отфильтрованную коллекцию, но обновляются только индикаторы количества записей по статусам, но сами “значки” или “карточки” на которые можно кликнуть, нет.
Вот собственно такая проблемка, перепробовал много вариантов уже: убирал fetch-план при выгрузке Suggestion
, делал загрузку KanbanEntity
прямо из базы, а не из кеша и т.д., ничего не помагает в таком раскладе.
До этого работало, но там не было кеша и был немного другой алгоритм, если вкратце то метод createAndGetCurrentSuggestionByKanban
удалял все KanbanEntity из базы, выгружал все Suggestion
, создавал новые KanbanEntity
, сохранял в базу и тут же отдавал результаты сохранения. Было удобно что не надо следить за обновлением Suggestion
и всегда всё было относительно “динамически”, но сильно страдала производительность уже при 400+ записях.