I\'m trying to change the code of this example thymeleafexamples-stsm, so I changed enum type for class type:
Type.java
public class Type {
p
I know this question is old but below answer may help someone as I could not find it easily.
To solve this issue, Thymeleaf uses Formatters to convert between Object and String.
In submitting phase (POST), Formatter Service will convert String back to
object.
First implement Formatter service for your Class to be used in tag:
@Service
public class TypeFormatter implements Formatter<Type> {
@Autowired
TypeService typeService;//Service -> DB
@Override
public String print(Type object, Locale locale) {
return (object != null ? object.getId().toString() : "");
}
@Override
public Type parse(String text, Locale locale) throws ParseException {
Integer id = Integer.valueOf(text);
return this.typeService.get(id);//return Type object form DB
}
}
It is very simple class with two methods:
Now, we've to tell Spring-Thymeleaf abbout our formatter or we may call it converter. To do that we've to register this formatter in our WebConfig (Configuration class whic extends WebMvcConfigurerAdapter):
@Configuration
@EnableWebMvc
@ComponentScan(value = { "your package" })
public class WebConfig extends WebMvcConfigurerAdapter {
....
//Formatters
@Autowired //Without autowire, this solution may not work
private TypeFormatter typeFormatter;
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(typeFormatter);
}
}
Now our solution is ready to be implemented in html file but how to tell Thymeleaf to apply conversion? Answer is by using th:field="*{type}" attribute and using Double-bracket syntax th:value="${{type}}":
<select th:field="*{type}">
<option th:value="NULL" th:text="---Select Type---"></option>
<option th:each="type : ${allTypes}" th:value="${{type}}" th:text="${type.type}">Wireframe</option>
</select>
Last thing to tell, sometimes we want to add a header to the dropdown list like "-----Select Type-----" in order to prevent default selection as well as explain to user. In this case you must set th:value="NULL" unless you'll get conversion error.
That error message basically says Spring don't know how to convert the string thymeleafexamples.stsm.business.entities.Type@2c08cec0
into an instance of Type. This is a bug on your code because it doesn't make any sense trying to do so.
You're not supposed to use the toString()
value of Object as a form dropdown identifier. You need to have a (much) better strategy for the code to identify the Type selected by user.
Common approach is to use the id
attribute:
<option th:each="type : ${allTypes}" th:value="${type.id}" th:text="${type.type}">Wireframe</option>
When the form is submitted, you then need to retireve an instance of Type based on its id name on your controller