0

In other places all @Autowired things work fine (dao in services, service in controller), but in one component isn't. service package has Abstract class and package with implementations. Inside implementation class @Autowired service is null, though same @Autowired service in controller works.

For the test, I separated the class from the Abstract class, but the problem did not disappear. All beans are always created.

package com.mp3.tagger.service.middleware;

    @Component(value = "localMatadataMiddleware")
    public class LocalMatadataMiddleware extends Middleware/*Abstract class*/ {

        @Autowired
        private ArtistService artistService;

        @Override
        public Artist findMetadata(String artistName, String trackName) {
            List<Artist> artist = artistService.findAll();//is null

            //another code...
        }
    } 

Config:

@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:persistence-mysql.properties" })
@ComponentScan({ "com.mp3.tagger" })
@EnableJpaRepositories(basePackages = "com.mp3.tagger.persistence.dao")
public class PersistenceJPAConfig {

    @Autowired
    private Environment env;

    public PersistenceJPAConfig() {
        super();
    }

    // beans

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan(new String[] { "com.mp3.tagger.persistence.entity" });

        final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());

        return em;
    }

    @Bean
    public DataSource dataSource() {
        final DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
        dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
        dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
        dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));

        return dataSource;
    }

    @Bean
    public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    final Properties additionalProperties() {
        final Properties hibernateProperties = new Properties();
        hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
        hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
        hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache"));
        hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache"));
        // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
        return hibernateProperties;
    }

I use Intellij Idea 2017.3.3

UPD:

I try to implement the pattern - chain of responsibility and create the instance

Middleware middleware = new LocalMatadataMiddleware();
middleware.findMetadata("Radiohead", "Fake Plastic Trees");

Abstract class:

public abstract class Middleware {

    private Middleware next;

    public Middleware linkWith(Middleware next) {
        this.next = next;
        return next;
    }

        //Main executable method of chain of responsibility
    public abstract Artist findMetadata(String artistName, String songName);

    public boolean checkIsCorrectAnswer(Artist artist, String artistName, String songName) {
        if (artist.getName().equals(artistName) || artist.getTrack().stream().anyMatch(e -> e.getTitle().equals(songName))) {
            return true;
        }
        return false;
    }

    protected Artist checkNext(String artistName, String songName) {
        if (next == null) {
            return new Artist();
        }
        return next.findMetadata(artistName, songName);
    }
}

Service:

@Service
@Transactional
public class ArtistService {

    @Autowired
    private ArtistDao artistDao;

    public ArtistService() {
        super();
    }

    public void createArtist(final Artist entity){
        artistDao.create(entity);
    }

    public void updateArtist(Artist entity){
        artistDao.update(entity);
    }

    public Artist findOne(long id){
        return artistDao.findOne(id);
    }

    public List<Artist> findAll(){
        return artistDao.findAll();
    }

    public Artist findTrackById(long id){
        return artistDao.findOne(id);
    }

    public void delete(Artist entity){
        artistDao.delete(entity);
    }

    public void deleteById(long id){
        artistDao.deleteById(id);
    }
}
  • Can you provide which Autowiring is null. There can be multiple reasons for it to be null. One of them can be the qualifier name. By default name of class reference object should be same as the @Qualifier name or if absent it is classname in camelcase format. Other reasons can be somewhere you might have initialized the object with new. Then autowiring doesn't work. If it is an abstract class then probably this can be the reason if following abstract design pattern. – Naruto Apr 02 '18 at 12:19
  • How do you obtain an instance of LocalMatadataMiddleware? – JB Nizet Apr 02 '18 at 12:23
  • Probably `ArtistService` (autowired class) is not in the package where you mentioned as component scan. – Vipin CP Apr 02 '18 at 12:30
  • They are in one 'service' package – Paul Pzhezinsky Apr 02 '18 at 12:38
  • You're only scanning the package com.mp3.tagger (and its subpackages). So a 'service' package wouldn't be scanned, and that should thus throw an exception. So, is ArtistService *really* in a 'service' package? And again, how do you obtain an instance of LocalMatadataMiddleware? – JB Nizet Apr 02 '18 at 12:50
  • Packages structure: com.mp3.tagger -> service(on same level controllers, persistence..) ->(Middleware.class)-> middleware(package with implementation) – Paul Pzhezinsky Apr 02 '18 at 13:05
  • You're creating the LocalMatadataMiddleware yourself. So Spring can't possibly autowire anything in that object, that it's completely unaware of. See the duplicate for details. – JB Nizet Apr 02 '18 at 13:06
  • Thank you, you helped me understand how the autowiring work – Paul Pzhezinsky Apr 02 '18 at 13:18

0 Answers0