Issue
I tried to upgrade the Spring Boot version for my application and found a difference in behavior. When switching from 2.2.7 to 2.2.8 (and higher), the conversion from identifier to database entity stops working.
Application:
@SpringBootApplication
public class DomainClassConverterTestApplication {
public static void main(String[] args) {
SpringApplication.run(DomainClassConverterTestApplication.class, args);
}
@Bean
CommandLineRunner initialize(ModelRepository modelRepository) {
return args -> {
Stream.of("Model 1", "Model 2", "Model X").forEach(name -> {
Model model = new Model();
model.setName(name);
modelRepository.save(model);
});
};
}
}
Controller:
@RestController
public class ModelController {
private final ModelRepository repository;
public ModelController(ModelRepository repository) {
this.repository = repository;
}
@GetMapping("/models/{id}")
public Model getModel(@PathVariable("id") Model model) {
return model;
}
@GetMapping("/models")
public Page<Model> findAllModels(Pageable pageable) {
return repository.findAll(pageable);
}
}
Model:
@Entity
public class Model {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
public Model() {}
public long getId() { return id; }
public void setId(long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@Override
public String toString() { return "Model{id=" + id + ", name='" + name + "'}"; }
}
After investigation of this problem, I discovered that the root cause of this is in the DomainClassConverter
class. I understand that the problem lies in the setApplicationContext
method. The method uses lazy initialization, and it adds converters to СonversionService
, but only after the first use. But this event never occurs because the converter is not registered in СonversionService
. Here is the method:
public void setApplicationContext(ApplicationContext context) {
this.repositories = Lazy.of(() -> {
Repositories repositories = new Repositories(context);
this.toEntityConverter = Optional.of(new ToEntityConverter(repositories, conversionService));
this.toEntityConverter.ifPresent(it -> conversionService.addConverter(it));
this.toIdConverter = Optional.of(new ToIdConverter(repositories, conversionService));
this.toIdConverter.ifPresent(it -> conversionService.addConverter(it));
return repositories;
});
}
Solution
It is a bug DATACMNS-1743 and was fixed in 2.2.8, 2.3.2, and higher.
Answered By - Mikhail Vaysman