Я пытался создать объект с другим объектом внутри, с формой, но Объект, выбранный из выпадающего списка, преобразуется в строку при возврате из формы Thymeleaf. Это сущности в моем проекте с соотношением 1: n между ними:
Пользователь сущности
//imports
@Entity
@Table(name = "USERS")
public class User {
@Id
@GeneratedValue
@Column( name ="USER_ID")
private int id;
@Column( name ="username")
private String username;
@Column( name ="password")
private String password;
@Column( name ="email")
private String email;
@OneToMany(fetch= FetchType.LAZY, mappedBy="user", cascade = CascadeType.ALL)
private List<Post> posts;
//setter & getters & toString
}
Сообщение сущности
//imports
@Entity
@Table(name="POSTS")
public class Post {
@Id
@GeneratedValue
@Column(name="POST_ID")
private int id;
@Column(name="tittle")
private String tittle;
@Column(name="text")
private String text;
@ManyToOne
@JoinColumn(name="USER_ID",referencedColumnName="USER_ID")
private User user;
//getters & setters & toString
Чтобы создать новую запись:
//In Controller
@RequestMapping(value = "/posts/new")
public String newPost(Model model) {
model.addAttribute("post", new Post());
model.addAttribute("users", userService.list());
return "addPost";
}
, который возвращает шаблон, имеющий эту форму:
<form th:action="@{/savePost}" th:object="${post}" method="post">
<tr>
<td><input type="hidden" th:field="${post.id}" /></td>
</tr>
<tr>
<td>Titulo</td>
<td>Texto</td>
<td>Usuario</td>
</tr>
<tr>
<td><input type="text" th:field="${post.tittle}"
th:value="${post.tittle}" /></td>
<td><input type="text" th:field="${post.text}"
th:value="${post.text}" /></td>
<td><select th:field="${post.user}">
<option th:each="user : ${users}" th:text="${user.username}"
th:value="${user.id}"></option>
</select></td>
</tr>
<tr>
<td colspan="3"><input class="btn btn-primary" type="submit"
value="GUARDAR"></td>
</tr>
</form>
Атрибут действия в форме вызывает:
@PostMapping("/savePost")
//@RequestMapping(value = "users/save",method = RequestMethod.POST)
public String savePost(@ModelAttribute Post post) {
postService.add(post);
return "redirect:/posts";
}
На этом этапе япопробуйте создать сообщение и выбрать пользователя из выпадающего списка, но при попытке сохранить его выдает следующую ошибку:
Ошибка поля в объекте «запись» в поле «пользователь»: отклоненное значение [16];коды [typeMismatch.post.user, typeMismatch.user, typeMismatch.com.julian.bootmvchibernate.model.User, typeMismatch];Аргументы [org.springframework.context.support.DefaultMessageSourceResolvable: codes [post.user, user];аргументы [];сообщение по умолчанию [пользователь]];сообщение по умолчанию [Не удалось преобразовать значение свойства типа 'java.lang.String' в требуемый тип 'com.julian.bootmvchibernate.model.User' для свойства 'user';вложенным исключением является org.springframework.core.convert.ConversionFailedException: не удалось преобразовать тип [java.lang.String] в тип [@ javax.persistence.ManyToOne @ javax.persistence.JoinColumn com.julian.bootmvchibernate.model.User]для значения «16»;вложенным исключением является java.lang.NullPointerException]
Поэтому я попытался реализовать средство форматирования следующим образом:
public class UserFormatter implements Formatter<User> {
@Autowired
@Qualifier("userService")
public GeneralService<User> userService;
@Override
public String print(User object, Locale locale) {
return (object != null ? object.getUsername() : "");
}
@Override
public User parse(String text, Locale locale) throws ParseException {
final Integer userId = Integer.parseInt(text);
return userService.get(userId);
}
}
Регистрация его:
@SpringBootApplication
public class BootmvchibernateApplication implements WebMvcConfigurer{
@SuppressWarnings("unchecked")
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(new UserFormatter());
}
public static void main(String[] args) {
SpringApplication.run(BootmvchibernateApplication.class, args);
}
}
Нопри использовании этого подхода обнаруживается следующая ошибка, которая просто открывает доступ к направлению / post / new (шаблон addPost не работает):
Произошла ошибка при разборе шаблона (template: "class path resource[templates / addPost2.html] ") org.thymeleaf.exceptions.TemplateInputException: при синтаксическом анализе шаблона произошла ошибка (template:" ресурс пути к классу [templates / addPost2.html] ") ...... Причина: org.attoparser.ParseException: Ошибка во время выполнения процессора 'org.thymeleaf.spring5.processor.SpringOptionFieldTagProcessor' (template: "addPost2" - строка 43, столбец 8) ..... Причина: org.springframework.core.convert.ConversionFailedException:Не удалось преобразовать тип [java.lang.String] в тип [@ javax.persistence.ManyToOne @ javax.persistence.JoinColumn com.julian.bootmvchibernate.model.User] fили значение «2»;Вложенным исключением является java.lang.NullPointerException по адресу org.springframework.core.convert.support.ConversionUtils.invokeConverter (ConversionUtils.java:47)
Если требуется дополнительная информация, сообщите мне, и я отправлю ее. РЕДАКТИРОВАТЬ: это хранилище, если кто-то заинтересован. github.com/JulianBautistaVelez/JPA_Spring_Excercise