Accessing Spring Beans inside AttributeConverter class

后端 未结 3 1414
逝去的感伤
逝去的感伤 2020-12-10 02:25

I\'m developing a Spring Data JPA application, and I\'ve created an AttributeConverter class in order to save an ArrayList of objects as JSON in a

3条回答
  •  长情又很酷
    2020-12-10 03:12

    Generally Ipandzic's answer is the right hint I guess. However it did not work for me how he described it. I argument-constructor also looks a little strange in a Spring-environment. I played around a bit and was able to use an AttributeConverter of the following form (indeed you do not need the @Converter-annotation or any other on the AttributeConverter-class itself):

    import javax.persistence.AttributeConverter;
    import org.springframework.beans.factory.annotation.Autowired;
    
    public class MyConverter implements AttributeConverter {
        @Autowired
        private MyBean mybean;
    
        public String convertToDatabaseColumn(String value) {
            return myBean.changeValue(value);
        }
    
        public String convertToEntityAttribute(String dbValue) {
            return myBean.undoChange(dbValue);
        }
    }
    

    But creating this class and upgrading to Spring-Boot 2.1 (including Spring 5.1, Hibernate 5.3 and JPA 2.2) did not do the trick for me. The thing was, that I used LocalContainerEntityManagerFactoryBean to configure my persistent storage which will not enable Dependency injection for AttributeConverters. Reading the first link Ipandzic posted suggests you have to bring LocalSessionFactoryBuilder into play somehow. That's why I ended up with the following configuration:

    //...
    
    @Bean
    public LocalSessionFactoryBean entityManagerFactory(DataSource dataSource, Environment env) {
        LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
        factory.setDataSource(dataSource);
    
        // somehow tell the factory where you entitiy-definitions are, this is just
        // one possibility of doing so:
        String entityPackage = JpaMarkerModel.class.getPackage().getName();
        log.info("EntityManager will scan for entities in package [{}].", entityPackage);
        factory.setPackagesToScan(entityPackage);
    
        return factory;
    }
    
    @Bean
    public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory);
        return transactionManager;
    }
    
    //...
    

    This "answer" is merely an addition to Ipandzi's, but maybe it helps some people to solve their problem quicker than I did.

提交回复
热议问题