Note that there are some explanatory texts on larger screens.

plurals
  1. POCDI: Property injection issue due to multiple inheritance and Generics abstraction
    primarykey
    data
    text
    <p>We use CDI for Dependency Injection. We need to implement a generic class, LazyAccountDataModel which will be used/injected by all data table beans (like in DataTableBean below). The generic LazyAccountDataModel needs to deal with a specific type of facade depending on the data table bean injecting it. I tried using Generics as an approach to determine which facade to use in the LazyAccountDataModel as follows but it throws the following exception:</p> <pre><code>@Named @RequestScoped public class DataTableBean { @Inject private LazyAccountDataModel&lt;IAccount, IAccountFacade&gt; lazyModel; } @Named @RequestScoped public class LazyAccountDataModel&lt;DO extends IDomainObject, FACADE extends IPersistableFacade&lt;DO&gt;&gt; extends LazyDataModel&lt;DO&gt; { @EJB (@Named doesn't work here due to WELD bug GLASSFISH-16186 which is not-optimal) private FACADE facade; private List&lt;DO&gt; datasource; @Override public List&lt;DO&gt; load(int first, int pageSize, String sortField, SortOrder sortOrder, Map&lt;String, String&gt; filters) { setRowCount((int) facade.findTotalCount()); // do more work on specific facade derivation (IAccountFacade in this case) return datasource; } } public interface IAccountFacade extends IPersistableFacade&lt;IAccount&gt; { public void logIn(String userName); } public interface IPersistableFacade&lt;DO extends IDomainObject&gt; extends IFacade&lt;DO&gt; { void create(DO domainData); List&lt;DO&gt; getAll(); long findTotalCount(); } </code></pre> <p>The exception stack trace </p> <pre><code>SEVERE: Exception while loading the app : WELD-001408 Unsatisfied dependencies for type [LazyAccountDataModel&lt;IAccount, IAccountFacade&gt;] with qualifiers [@Default] at injection point [[field] @Inject private view.dashDOard.DataTableBean.lazyModel] org.jDOss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [LazyAccountDataModel&lt;IAccount, IAccountFacade&gt;] with qualifiers [@Default] at injection point [[field] @Inject private view.dashboard.DataTableBean.lazyModel] at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:270) at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:106) at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:129) at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:351) at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:336) at org.jboss.weld.bootstrap.WeldDOotstrap.validateBeans(WeldDOotstrap.java:396) at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:190) at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:128) at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:306) at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:462) at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240) at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:382) at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:355) at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370) at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1064) at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96) at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1244) at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1232) at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:459) at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:209) at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:168) at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:238) at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828) at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725) at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019) at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225) at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) at com.sun.grizzly.ContextTask.run(ContextTask.java:71) at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) at java.lang.Thread.run(Thread.java:662) </code></pre> <p>Our problem is quite similar to the following post: <a href="https://stackoverflow.com/questions/6793756/cdi-producer-method-for-data-model">CDI producer method for data model</a>. Can anyone provide pointers on how we can inject LazyAccountDataModel and specify to it which facade needs to be used?</p> <p>One possible solution would be to inject the specific facade type along with the LazyAccountDataModel and then set the facade type explicitly. However, this is not a clean solution:</p> <pre><code>@Named @RequestScoped public class DataTableBean { @EJB private IAccountFacade facade; @Inject private LazyAccountDataModel&lt;IAccount&gt; lazyModel; @PostConstruct public void init() { // would rather this stayed decoupled/handled by IoC framework lazyModel.setfacade(facade); } @Named @RequestScoped public class LazyAccountDataModel&lt;DO extends IDomainObject&gt; extends LazyDataModel&lt;DO&gt; { private IPersistableFacade&lt;DO&gt; facade; private List&lt;DO&gt; datasource; @Override public List&lt;DO&gt; load(int first, int pageSize, String sortField, SortOrder sortOrder, Map&lt;String, String&gt; filters) { setRowCount((int) facade.findTotalCount()); // do more work on specific facade derivation (IAccountFacade in this case) return datasource; } public void setfacade(IPersistableBusinessObjectfacade&lt;DO&gt; facade) { this.facade = facade; } } </code></pre> <p>Another solution may be to use contextual producers like: <a href="http://blog.frankel.ch/further-into-cdi" rel="nofollow noreferrer">http://blog.frankel.ch/further-into-cdi</a> But this doesn't seem to work for 2-deep layers of abstraction. This use case would be easily implemented in Spring by specifying nested properties in the context XML. Can anyone provide any inputs on how this can be done in CDI? Any help would be appreciated.</p> <p>Thanks.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload