Вложенный набор Thymeleaf‹Object›

У меня проблема с доступом к вложенному набору объектов. Я определил следующие объекты:

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "site")
public class Site {
    @Id
    @GeneratedValue(strategy = GerationType.IDENTITY)
    @Column(name="id", updatable=false,nullable=false)
    private Long id;

    private String siteName;
    private String siteLocation;

    @OneToMany(cascade=CascadeType.ALL, mappedBy = "site")
    private Set<Rack> rack = new HashSet<>();
}

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "rack")
public class Rack { 

    @Id
    @GeneratedValue(strategy = GerationType.IDENTITY)
    @Column(name="id", updatable=false,nullable=false)
    private Long id;
    private String rackName;
    private String rackAssetTag;
    private String rackCMDBCode;

    @ManyToOne
    @JoinColumn(name = "site_id")
    private Site site;

    @OneToMany(cascade=CascadeType.ALL, mappedBy = "box")
    private Set<Box> box = new HashSet<>();
}

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "box")
public class Box {  
    @Id
    @GeneratedValue(strategy = GerationType.IDENTITY)
    @Column(name="id", updatable=false,nullable=false)
    private Long id;
    private boxAssetTag;
    private boxCMDBCode;

    ManyToOne
    @JoinColumn(name = "rack_id")
    private Rack rack;

}

Все сопоставления отношений работают на высшем уровне. Проблема в том, что когда я хочу создать для этого красивую вложенную таблицу (форматирование css и условная проверка тимелефа удалены, поскольку это не имеет значения):

<div>
    <table>
        <thead>
            <tr>
                <th>Rack name</th>
                <th>Rack asset tag</th>
                <th>Rack CMDB code</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="rack:${site.rack}">
                <td th:text="${rack.rackName}"></td>
                <td th:text="${rack.rackAssetTag}"></td>
                <td th:text="${rack.rackCMDBCode}"></td>
            </tr>
            <tr>
                <td>
                    <table>
                        <thead>
                            <tr>
                                <th>Box asset tag</th>
                                <th>Box CMDB code</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr th:each="box:${rack.box}">
                                <td th:text="${box.boxAssetTag}">
                                <td th:text="${box.boxCMDBCode}">
                            </tr>
                        </tbody>
                    </table>
                </td>
            </tr>
        </tbody>
    </table>
</div>

Контроллер добавляет один объект «сайт» в модель, которая содержит все отношения. При доступе к странице я получаю сообщение об ошибке: Свойство или поле "ящик" не может быть найдено в нулевом значении

Я думаю, что когда я перехожу ко второй таблице, тимелеаф теряет контекст стойки объектов, созданной во внешней таблице. Поэтому, когда я пытаюсь вызвать th:each во внутренней таблице, нет объекта стойки для выполнения ${rack.box}. Вопрос в том, как получить доступ к «более глубокому» объекту в тимелеафе, не теряя контекст объекта выше?

С уважением, Ярек.


person Jarek Brocki    schedule 02.06.2020    source источник


Ответы (1)


Итак, мне удалось выработать решение. Я напишу это. Может быть, кому-то когда-нибудь это понадобится.

Таким образом, идея состоит в том, чтобы циклически проходить по каждому объекту, но по элементу body, а не по строке. Это позволяет вам иметь контекст объекта намного шире

<div>
<table>
    <thead>
        <th>Rack name</th>
        <th>Rack asset tag</th>
        <th>Rack CMDB code</th>
    </thead>
    <tbody th:each="rack:${site.rack}">
        <tr>
            <td th:text="${rack.rackName}"></td>
            <td th:text="${rack.rackAssetTag}"></td>
            <td th:text="${rack.rackCMDBCode}"></td>
        </tr>
        <tr>
            <td>
                <table>
                    <thead>
                        <tr>
                            <th>Box asset tag</th>
                            <th>Box CMDB code</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr th:each="box:${rack.box}">
                            <td th:text="${box.boxAssetTag}">
                            <td th:text="${box.boxCMDBCode}">
                        </tr>
                    </tbody>
                </table>
            </td>
        </tr>
    </tbody>
</table>

person Jarek Brocki    schedule 02.06.2020