I have following CDI Bean:
@SessionScoped
public class ReportService implements Serializable {
private static final long serialVersionUID = 1L;
private MyDao myDao;
@Inject
public ReportService(MyDao myDao) {
this.myDao = myDao;
}
}
@RequestScoped
public class MyDao extends AbstractDao<Order> {
protected MyDao() {
}
@Inject
public MyDao(EntityManager em) {
super(em);
}
}
If i start my webapplication (Tomcat with Weld) the following Exception is thrown:
WELD-001435: Normal scoped bean class com.myorg.ReportService is not proxyable because it has no no-args constructor - Managed Bean [class com.myorg.ReportService] with qualifiers [@Any @Default].
How is it possible to use constructor injection in a SessionScoped Bean? Is it safe just to add a package-visible no-args constructor?
I already searched a lot, but i did not find any information about passivating a CDI Bean whitch uses Constructor Injection.
The error you are getting is based on CDI specification requirements, namely the need to have no-args constructor. When instantiating the object, CDI will of course prioritize a constructor annotated with @Inject
, so don't worry about that.
The real reason why you need no-args one is for proxies. Weld/CDI will try to create one or more proxies of your object, which are basically an enriched delegates. In order to instantiate them, you want to invoke no-arg constructor - think of it as Java limiation, you shouldn't be instantiating objects without calling constructors. Therefore the spec mandates the need for no-arg constructor. As a matter of fact, Weld itself allows you to bypass this need in certain cases, but I strongly suggest against it.
Is it safe just to add a package-visible no-args constructor?
Yes, go ahead and do that.