Search code examples
jodd

jodd cannot manage to inject two beans


I have a DAO and a Service class each implements a interface:

public interface TemperatureDao extends GenericDAO<TemperatureLog> {

    public abstract List<TemperatureLog> getLastHourTemperatures();
}

@PetiteBean(value="temperatureDao",wiring=WiringMode.AUTOWIRE)
public class TemperatureDaoImpl extends GenericAbstractDAO<TemperatureLog> implements TemperatureDao {

    @Override
    public List<TemperatureLog> getLastHourTemperatures(){                  
        //do stuff here
        return temps;
    }
}

and

public interface TemperatureService {

    public abstract boolean save(TemperatureLog t);
    public abstract List<TemperatureLog> getLastHoutTemperatures();
}

@PetiteBean(value="temperatureService",wiring=WiringMode.AUTOWIRE)
public class TemperatureServiceImpl extends GenericService implements TemperatureService {

    @PetiteInject
    private TemperatureDao temperatureDao;      

    public TemperatureDao getTemperatureDao() {
        return temperatureDao;
    }

    public void setTemperatureDao(TemperatureDao temperatureDao) {
        this.temperatureDao = temperatureDao;
    }

    @Override
    public boolean save(TemperatureLog t){

        try {
            temperatureDao.saveOrUpdate(t);
            return true;
        }catch(Exception e) {
            return false;
        }
    }

    @Override
    @Transaction(propagation = JtxPropagationBehavior.PROPAGATION_REQUIRED, readOnly = true,isolation=JtxIsolationLevel.ISOLATION_READ_COMMITTED)
    public List<TemperatureLog> getLastHoutTemperatures(){

        return temperatureDao.getLastHourTemperatures();        
    }   
}

and the problem is that temperatureDao is not injected as i get NullPointerException here:

return temperatureDao.getLastHourTemperatures();  

The logs looks fine to me :

127 [DEBUG] j.p.PetiteBeans.registerPetiteBean:244 - Registering bean: temperatureDao of type: TemperatureDaoImpl in: SingletonScope using wiring mode: AUTOWIRE
128 [DEBUG] j.p.ProxettaBuilder.process:187 - processing: ro/videanuadrian/smartHome/dao/impl/TemperatureDaoImpl
128 [DEBUG] j.p.ProxettaBuilder.define:228 - proxy not applied ro.videanuadrian.smartHome.dao.impl.TemperatureDaoImpl
134 [DEBUG] j.p.PetiteBeans.registerPetiteBean:244 - Registering bean: temperatureService of type: TemperatureServiceImpl in: SingletonScope using wiring mode: AUTOWIRE
135 [DEBUG] j.p.ProxettaBuilder.process:187 - processing: ro/videanuadrian/smartHome/services/impl/TemperatureServiceImpl
139 [DEBUG] j.p.ProxettaBuilder.define:243 - proxy created ro.videanuadrian.smartHome.services.impl.TemperatureServiceImpl

So, any idea what I'm I missing here?


Solution

  • I am posting new answer to explain better what is going on.

    What happens here is that you have proxy created on TemperatureServiceImpl and registered it as a PetiteBean, which is perfectly correct :) So, Petite container gets the proxified class, which is a subclass of your service implementation.

    When Petite does the wiring, it is scanning the proxy class and, therefore, it can not see the annotated private field in the super class (which is the original TemperatureServiceImpl).

    You can fix this in two ways:

    1. either by removing private modifier (and use anything else) - than container will 'see' the field in the subclass, or

    2. simply annotating the e.g. getTemperatureDao() method with @PetiteInject and leaving the field as it is.

    Hope this explains what is going on. I will try to address this in upcoming 3.6 release.