Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @autowired does not work

I have a problem with spring DI via annotations, here is my app:

@Service
public class Test {

    @Autowired
    private GpsPointEntityDao gpsPointEntityDao;

    public void test() {

        if (gpsPointEntityDao == null)
            System.out.println("It's null!\n" + gpsPointEntityDao);

    }
}

generic interface:

public interface GenericDao<T extends DomainObject> {

    public T find(long id);

    public List<T> getAll();

    public void save(T object) throws DataAccessException;

    public void delete(T object) throws DataAccessException;

}

concrete interface:

public interface GpsPointEntityDao extends GenericDao<GpsPointEntity> {}

abstract implementation:

abstract class AbstractGenericDaoJpa<T extends DomainObject> implements GenericDao<T> {

    private final Class<T> entityType;

    protected EntityManager entityManager;

    public AbstractGenericDaoJpa() {
        this.entityType = (Class<T>) GenericTypeResolver.resolveTypeArgument(getClass(), GenericDao.class);
    }

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Transactional
    @Override
    public T find(long id) {
        return entityManager.find(entityType, id);
    }

    @Transactional
    @Override
    public List<T> getAll() {
        return entityManager.createQuery("SELECT e FROM " + entityType.getName() + " e").getResultList();
    }

    @Transactional
    @Override
    public void save(T object) throws DataAccessException {
        entityManager.persist(object);
    }

    @Transactional
    @Override
    public void delete(T object) throws DataAccessException {
        entityManager.remove(object);
    }

}

concrete class:

@Repository
public class GpsPointEntityDaoJpa extends AbstractGenericDaoJpa<GpsPointEntity> implements GpsPointEntityDao {}

And my appcontext:

<context:component-scan base-package="com.test"/>

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

<bean id="entityManagerFactory"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
      p:dataSource-ref="basicDataSource"/>

<bean id="transactionManager"
      class="org.springframework.orm.jpa.JpaTransactionManager"
      p:entityManagerFactory-ref="entityManagerFactory"/>

<tx:annotation-driven mode="proxy" transaction-manager="transactionManager"/>

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

The result of app is:

It's null!

I have been spending all day for searching the problem but unsuccessfully. Where someone sees a problem?

I found this message in logs:

INFO  org.springframework.context.support.ClassPathXmlApplicationContext - Bean 'entityManagerFactory' of type [class org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
like image 256
pierre tautou Avatar asked Aug 10 '11 16:08

pierre tautou


1 Answers

I don't see a problem with that. With roughly the same code as you posted, I ran this:

public static void main(String[] args) {
    Test bean = new ClassPathXmlApplicationContext("/applicationContext.xml").getBean(Test.class);
    bean.test();
}

The Test bean was injected correctly. I can make my test project available if you want to take a look. Are you sure you're getting an injected version of Test? How are you obtaining it?

Edit: Your instance isn't being injected because you're instantiating it yourself instead of letting Spring do it. Unless you use AspectJ to inject objects, Spring can/will only inject objects that it is managing. When you call new Test(), you're not getting the instance from Spring, and Spring doesn't know anything about that instance you've created.

like image 183
Ryan Stewart Avatar answered Oct 20 '22 01:10

Ryan Stewart