Зачем комбинация SessionAttributes с ModelAttribute

Зачем???По факту первое делает так чтобы элемент который добавлен в модель был виден во всей сессии, а второе делает так чтобы элемент указанный в параметрах ModelAttribute(который над методом) был добавлен в модель.Но ведь ModelAttribute вызывается всегда,значит элемент будет в модели всегда.Зачем их комбинация,если можно использовать одно из них??И то и то делает почти одно и то же .
Снизу пример комбинации


@RequestMapping("/store")

@SessionAttribute("form")
public class MenuController {

     @ModelAttribute("form")

     public Form createForm() {

     return new Form();

     }

     @RequestMapping("/book")

     public Sring bookList(@ModelAttribute("form") Form form){

     //processing the form

     }

}```

Ответы (2 шт):

Автор решения: AndrewThomas

Метод, помеченный аннотацией @ModelAttribute, автоматически добавляет в Model каждого метода, имеющего аннотацию @RequestMapping и ее производные, соответствующий объект, возвращаемый из такого метода (в приведенном примере - Form). Но этот объект - каждый раз новый, "чистый", если можно так выразиться, за исключением методов, где значение полей такого объекта заполняется через форму (html, jsp и т.д.).

Аннотация @SessionAttribute, в свою очередь, позволяет сохранять объект в spring-сессии (не путать с http-сессией!), т.е. если посредством какой-либо формы поля объекта, выступающего в качестве @ModelAttribute, были однажды заполнены, их значения будут доступны из любого метода в рамках того же контроллера, помеченного аннотацией @RequestMapping и ее производными, пока не будут принудительно очищены.

@SessionAttributes(names = {"form"})
public class MenuController {

    @ModelAttribute("form")
    public Form createForm() {
        return new Form();
        // 1) этот метод автоматически добавляет объект Form в Model,
        // доступный из любого метода с аннотацией типа @RequestMapping
    }
     
    @PostMapping("/book")
    public String createBooks(@ModelAttribute("form") Form form) {
        // 2) здесь объект Form мог быть заполнен какими-то значениями через форму
        return "bookPage";
    }

    @GetMapping("/book")
    public String bookList(@ModelAttribute("form") Form form){
        // 3) если метод вызван после метода в пункте 2 и в объекте Form появились какие-то значения,
        // то здесь они будут доступны, т.е. объект Form не создастся заново пустой
        return "bookListPage";
    }

    @GetMapping("/clear")
    public String clear(SessionStatus status) {
        status.setComplete();
        // 4) таким способом можно очистить объект Form, если это необходимо по логике приложения
        return "somePage";
    }
}

Для наглядности можно почитать следующие статьи с Хабра и Baeldung

→ Ссылка
Автор решения: Anton Kozytskyi

Небольшое уточнение. Метод, помеченный через аннотацию @ModelAttribute("form"), будет выполнен только, если атрибут "form" еще не создан - то есть null. Другими словами, при первом вызове формы он будет заполнен в new Form(). Больше вызываться не будет, так как на следующих шагах формы атрибут "form" уже будет существовать и далее он будет лишь постепенно заполняться в шагах формы.

→ Ссылка