Дерево не создается

Не могу понять, как создать дерево…
Есть таблица с id (int) и pid-ссылкой. При создании по примеру https://demo.jmix.io/sampler/#main/0/sample?id=tree-simple не получается дерева.

Контроллер использую StandardLookup, т.к. с ScreenFragment проект не запускается. По итогу смог добиться только такого результата: плоская одноколоночная таблица вместо дерева слева, и все строки справа вместо выборки только “листьев дерева”. Но тут еще не понял как задавать отношение для выборки в параметр query.

И дополнительно вопрос: возможно ли сразу редактировать значения в правой части, без открытия отдельно окна?

image

package ru.sgrc.kmh_jmix.entity.settings;

import io.jmix.core.metamodel.annotation.InstanceName;
import io.jmix.core.metamodel.annotation.JmixEntity;
import io.jmix.core.metamodel.annotation.Store;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.Date;

@Store(name = "kmh")
@JmixEntity
@Table(name = "T_CONFIG")
@Entity(name = "jmix_Config")
public class Config {

    @Column(name = "CONFIG_ID", nullable = false)
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "CONF_TYPE", nullable = false, columnDefinition = "Тип")
    @NotNull
    private String confType;

    @Column(name = "CONF_VALUE", nullable = false, columnDefinition = "Значение")
    @NotNull
    private String confValue;

    @InstanceName
    @Column(name = "CONFNAME", nullable = false, columnDefinition = "Название настройки")
    @NotNull
    private String name;

    @NotNull
    @JoinColumn(name = "CONFIG_PID", nullable = false, referencedColumnName = "CONFIG_ID")
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    private Config parentConfig;

    public Config getParentConfig() {
        return parentConfig;
    }

    public String getName() {
        return name;
    }

    public String getConfValue() {
        return confValue;
    }

    public void setConfValue(String confValue) {
        this.confValue = confValue;
    }

    public Long getConfType() {
        return confType;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

package ru.sgrc.kmh_jmix.screen.settings.config;

import io.jmix.ui.model.CollectionContainer;
import io.jmix.ui.screen.LookupComponent;
import io.jmix.ui.screen.StandardLookup;
import io.jmix.ui.screen.UiController;
import io.jmix.ui.screen.UiDescriptor;
import org.springframework.beans.factory.annotation.Autowired;
import ru.sgrc.kmh_jmix.entity.settings.Config;

@UiController(“jmix_Config.browse”)
@UiDescriptor(“config-browse.xml”)
@LookupComponent(“configTable”)
public class ConfigBrowse extends StandardLookup {
}

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://jmix.io/schema/ui/window"
        caption="msg://ru.sgrc.kmh_jmix.screen.settings/ConfigBrowse.caption"
        focusComponent="configTree">
    <data>
        <collection id="configTreeDc" class="ru.sgrc.kmh_jmix.entity.settings.Config">
            <fetchPlan extends="_local">
                <property name="parentConfig" fetchPlan="_local"/>
            </fetchPlan>
            <loader id="configTreeLoader">
                <query>
                    <![CDATA[select e from jmix_Config e where e.confType = 0 order by e.id]]>
                </query>
            </loader>
        </collection>
        <collection id="configDc" class="ru.sgrc.kmh_jmix.entity.settings.Config">
            <fetchPlan extends="_local">
                <property name="parentConfig" fetchPlan="_local"/>
            </fetchPlan>
            <loader id="configLoader">
                <query>
                    <![CDATA[select v from jmix_Config v]]>
                </query>
            </loader>
        </collection>
    </data>
    <facets>
        <dataLoadCoordinator auto="true"/>
    </facets>
    <layout>
        <split orientation="horizontal" height="100%" width="100%" maxSplitPosition="30%" minSplitPosition="200px">
            <vbox spacing="true" height="100%">
                <tree id="configTree"
                      captionProperty="name"
                      dataContainer="configTreeDc"
                      height="100%"
                      hierarchyProperty="parentConfig"
                      width="100%"/>
            </vbox>
            <vbox spacing="true" height="100%">
                <table id="configTable" height="100%" width="100%" dataContainer="configDc">
                    <actions>
                        <action id="edit" type="edit"/>
                        <action id="refresh" type="refresh"/>
                        <action id="save" type="refresh"/>
                    </actions>
                    <buttonsPanel alwaysVisible="true">
                        <button id="configsTableEditBtn" action="configTable.edit"/>
                        <button id="configsTableRefreshBtn" action="configTable.refresh"/>
                        <button id="configsTableSaveBtn" action="configTable.save"/>
                    </buttonsPanel>
                    <columns>
                        <column id="name"/>
                        <column id="confValue"/>
                    </columns>
                </table>
            </vbox>
        </split>
    </layout>
</window>

Добрый день.

При создании экранов для сущности, в Студии можно выбрать тип таблицы, и в экране автоматически сгенерируется дерево для отображения сущности.

image

Да, для этого выберите при создании экрана тип Master-details screen.

Прикладываю демо проект demo-tree.zip (84.5 КБ)

Так нет, нужна не таблица (TreeTable), а именно дерево (Tree). То что на картинке (в заголовке вопроса) в левой части.
На картинке справа выведена вся таблица - тестировал подходы…
В названии элемента указан id, parentId указан в скобках в названии. Root имеет оба значения =0.

И получается что при использовании, компонент Tree выводит все записи подряд в колонку, без вложенности. И дерево из примера не получается…
Или может есть какие ограничения/правила на использование? (как например в мастер-детайл окне обязателен элемент с id=table и если такового нет, то окно не грузится)

Проблема скорее всего в дата контейнере, который вы используете в дереве, если вы будете использовать стандартный контейнер configDc, все будет отображаться корректно, возможно, ваш запрос в query для configTreeDc возвращает данные, из которых невозможно составить иерархию.

1 симпатия

Да, действительно, проблема была в data-контейнере, а именно в плане выборки. Она заключалась в следующем: при работе с UUID идентификацией данных (как в примере выше) код отрабатывал корректно и дерево строилось, при любом варианте плана выборки.

В случае использования INT-идентификаторов и выборки по SAMPLER-примеру получался плоский список. Причем путем “натыкивания” по структуре он мог даже свернуться в дерево, и не факт что корректно. При этом план выборки был из примера и выглядел так:
<fetchPlan extends="_local">
<property name="parentTask" fetchPlan="_local"/>
</fetchPlan>

Дерево получилось с выборкой по плану без указания колонки сопряжения в дерево:
<fetchPlan extends="_local"/>

При этом тип плана base или local на результат не повлиял.

1 симпатия