Search code examples
jakarta-eedependency-injectioncdijboss-weld

Weld @Produces dependency has null injection point


I have a generic DAO with a non default constructor that looks something like this (not actually to do with vehicles I'm just trying to provide a simple example)

public class GenericVehicleDao<T extends Vehicle> {
    private Class<T> clazz;

    @Inject
    private DaoHelper daoHelper;

    public GenericDao(Class<T> clazz)
    {
        this.clazz = clazz;
    }
}

I have another class with some @Produces methods which uses this constructor so for example

public class AppProducer {

    @Produces
    public GenericDao<Car> createCar() {
        return new GenericDao(Car.class);
    }

    @Produces
    public GenericDao<Truck> createTruck() {
        return new GenericDao(Truck.class);
    }

}

I can then inject that DAO into a service layer eg.

@Stateless
public class VehicleService {

    @Inject
    private GenericVehicleDao<Car> carDao;

}

That Car DAO injects fine into the service layer, however I'm finding that the DAO's injected DaoHelper is null after the DAO has been constructed. If I inject the DaoHelper into the service layer then that injects fine, I'd rather do the injection in the DAO itself however. I have tried switching from field injection to setter injection but I have the same issue.


Solution

  • Once again answering my own question, this may be useful to others. After some more Googling I spotted the following in the Weld documentation

    There's one potential problem with the code above. The implementations of CreditCardPaymentStrategy are instantiated using the Java new operator. Objects instantiated directly by the application can't take advantage of dependency injection and don't have interceptors.

    If this isn't what we want, we can use dependency injection into the producer method to obtain bean instances:

    What this means is I can change my Producer methods to take the following format and then it works fine

    @Produces
    public GenericDao<Car> createCar(DaoHelper helper) {
        GenericDao<Car> carDao = new GenericDao<>(Car.class);
        carDao.setHelper(helper);
        return carDao;
    }