I'm trying to write custom JSF converter for entity classes. I use spring-data and spring-boot in my project.
Know i have a lot of classes looks like `this:
@Component("myFirstConverter")
class MyFirstConverter implements Converter {
@Autowired
private MyFirstRepository myFirstRepository;
@Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
return myFirstRepository.findOne(Long.parseLong(value));
}
//...
}
I created custom class EntityConverter. It works with CrudRepository. But i can't understand how to programmatically create array of beans and inject into each bean corresponded repository.
Know I tried to write @Configuration class with this code:
@Configuration
class MyConfig extends WebMvcConfigurerAdapter
@Bean
public static BeanFactoryPostProcessor registerConverters(ApplicationContext context) {
Map<String, Class<? extends CrudRepository>> converterBeans = new HashMap<>();
converterBeans.put("firstEntity", firstEntityRepository.class);
converterBeans.put("secondEntity", secondEntity.class);
return factory -> {
for (val entry : converterBeans.entrySet()) {
CrudRepository bean = context.getBean(entry.getValue()
factory.registerSingleton(entry.getKey()
.concat("Converter"), new EntityConverter(
entry.getKey(), bean));
}
};
But it doesn't work. Application failed in initialization.
19:07:59.546 [WARN ] o.s.c.support.AbstractApplicationContext:551 -
Exception encountered during context initialization - cancelling
refresh attempt:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'myFirstRepository': Cannot create inner bean
'(inner bean)#1fdfafd2' of type
[org.springframework.orm.jpa.SharedEntityManagerCreator] while setting
bean property 'entityManager'; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name '(inner bean)#1fdfafd2': Cannot resolve
reference to bean 'entityManagerFactory' while setting constructor
argument; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$fe46103]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$fe46103.<init>()Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fumoRepository': Cannot create inner bean '(inner bean)#1fdfafd2' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#1fdfafd2': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$fe46103]: No default constructor found; nested exception is java.lang.NoSuchMethodException:
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfigurati
on$$EnhancerBySpringCGLIB$$fe46103.<init>()
UPD:
Answer WiPU allowed to solve the problem. I changed my registerConverters method like this:
@Configuration
class MyConfig extends WebMvcConfigurerAdapter
@Bean
public static BeanFactoryPostProcessor
registerConverters(ApplicationContext context) {
Map<String, Class<? extends CrudRepository>> converterBeans = new HashMap<>();
converterBeans.put("firstEntity", firstEntityRepository.class);
converterBeans.put("secondEntity", secondEntity.class);
return factory -> {
BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry)
factory;
for (val entry : converterBeans.entrySet()) {
BeanDefinitionBuilder b =
BeanDefinitionBuilder.genericBeanDefinition(EntityConverter.class)
.addPropertyReference("repository", entry.getKey().concat("Repository"))
;
beanFactory.registerBeanDefinition(entry.getKey().concat("Converter"), b.getBeanDefinition());
factory.registerSingleton(entry.getKey()
.concat("Converter"), new EntityConverter(
entry.getKey(), bean));
}
};