Thymeleaf th: каждый не может найти объект - PullRequest
0 голосов
/ 12 февраля 2019

Я использую Thymeleaf с springboot 2.1.2, и у меня есть проблема с Thymeleaf th: каждый тег.Вот мой код:

    <tr th:each="addr : ${user.addressList}">
        <td><input type="text" th:value="${addr.name}" th:field="${addr.name}"></td>
        <td><input type="text" th:value="${addr.phone}" th:field="${addr.phone}"></td>
        <td><input type="text" th:value="${addr.location}" th:field="${addr.location}"></td>
        <td><a th:href="@{/user/addr/del/{id}(id=${addr.id})}">del</a></td>
    </tr>

Однако я сталкиваюсь со следующим исключением:

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'addr' available as request attribute

Отладчик говорит, что не может найти переменную, однако я уверен, что представлениеимеет объект привязки с именем 'user', потому что я использую его еще где-то впереди.

Вот мой контроллер и мои сущности:

@GetMapping("/profile")
public String getProfile(HttpServletRequest request, Model model) {
    HttpSession session = request.getSession(false);
    String email = (String) session.getAttribute("userId");
    User user = userService.getProfile(email);
    model.addAttribute("user", user);
    return "user/profile";
}

@Entity
public class User {

    @Id
    private String email;
    private String userName, password;
    private int pts;    //积分
    private int status= Flags.USER_EXIST;

    @OneToMany(targetEntity = Address.class
        , fetch = FetchType.LAZY, mappedBy = "user"
        , cascade = {CascadeType.PERSIST,CascadeType.REMOVE})
    private List<Address> addressList = new ArrayList<>();

    //constructors and getters and setters below...
}

@Entity
public class Address {
    @Id
    @GeneratedValue //去掉这个注解会导致一系列bug
    private long id;
    private String name, phone, location;
    @ManyToOne(targetEntity = User.class)
    private User user;

    //constructors and getters and setters below...
}

Я следую учебному пособию здесь и я не могу найти никакой разницы между моим: каждое использование и учебник.Не могли бы вы помочь мне?

ОБНОВЛЕНИЕ ===========================================>

Вот мой код для UserService.getProfile (String email):

@Override
public User getProfile(String email) {
    Optional<User> res = userRepository.findById(email);
    return res.isPresent() ? res.get() : null;
}

ОБНОВЛЕНИЕ еще раз ================================================================>

Подведите итог того, что я сделал до сих пор:

1) используйте FetchType.EAGER в классе пользователя

2) заставить репозиторий получить соответствующий адрес, напечатав addressList:

user.getAddressList().stream().forEach(x -> System.out.println(x.getLocation()));

3) удалить th: каждый блок и перезапустить мое приложение, исключений нет;когда я добавляю обратно блок, мое приложение снова выходит из строя ...

Все эти меры, кажется, не помогают мне ...

Ответы [ 3 ]

0 голосов
/ 12 февраля 2019

Вы получаете эту ошибку: -

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'addr' available as request attribute

Поскольку вы используете аннотацию @ModelAttribute на вашем контроллере.
Вы пытаетесь отправить объект с именем addr на ваш контроллер после отправки, однако вы не отправляете объект с точным именем addr в / из контроллера, откуда вы открываете запрошенный htmlстр.

Вот краткий пример того, как вы отправляете объект, используя аннотацию @ModelAttribute: -

1.) Запрошенный вами контроллер, откуда выОткрытие запрашиваемой HTML-страницы будет выглядеть примерно так: -

@RequestMapping("/test")
    public String test(HttpServletRequest request,Model model){

    //your code
  model.addAttribute("addr",new MyTest());
  return "yourRequestedPage";
  }

2.) И после отправки ваш следующий контроллер будет выглядеть примерно так: -

@RequestMapping("/testAfterSubmit")
    public String someMethodName(@ModelAttribute("addr") MyTest myTestClass,HttpServletRequest request,Model model ) {
//your code . . 

 }

PS - Для получения дополнительной информации о том, что делает / является @ModelAttribute, вот краткий справочник: -

Что такое @ModelAttribute в Spring MVC?

0 голосов
/ 12 февраля 2019

Я думал, что нашел проблему ... Это очень сложно ... Я редактирую th: каждый блок, и теперь это похоже на:

    <tr th:each="addr : ${user.addressList}">
        <td><input type="text" th:value="${addr.name}"></td>
        <td><input type="text" th:value="${addr.phone}"></td>
        <td><input type="text" th:value="${addr.location}"></td>
        <td><a th:href="@{/user/addr/del/{id}(id=${addr.id})}">del</a></td>
    </tr> 

Нашли ли вы разницу?Да, я удаляю тег th: field!В исходном коде я связал атрибут объекта Address в списке с итератором!Может быть, это только для чтения, я думаю ... поэтому компилятор будет ожидать объект с именем 'addr' в модели, конечно, это не получится ...

Эта ошибка предупреждает меня, чтобы отделить функцию модификации и функцию представленияв соответствующий вид ...

0 голосов
/ 12 февраля 2019

Проблема не связана с JPA в конце концов.Проблема в том, как вы используете th:field.См. Документацию о правильном использовании: https://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#dynamic-fields

Попробуйте:

<tr th:each="addr,addrStat : ${user.addressList}">
        <td><input type="text" th:value="${addr.name}" th:field="*{addressList[__${addrStat.index}__].name}"></td>

...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...