deltaspike repository entitymanagerresolver error with two produces entityManger - cdi

Sorry for my english, I've a war project with cdi 1.0, deltaspike 0.5 and primefaces 4.0, when I'm trying to use #Respository with #EntityManagerConfig because I've two produces for entityManager with diferent #Qualifiers, I'm using glassfish 4 for application server this is de code for Repository, Produces and EntityManagerResolver:
Repository:
#Repository(forEntity = User.class)
#EntityManagerConfig(entityManagerResolver = HbsWebEntityManagerResolver.class, flushMode = FlushModeType.AUTO)
public abstract class UserRepository extends
AbstractEntityRepository<User, Integer> {
#Query(named = User.BY_LOGIN)
public abstract User findByLoginEqual(#QueryParam("login") String login);
}
EntityManagerResolver:
public class HbsWebEntityManagerResolver implements EntityManagerResolver{
#Inject
#HbsWeb
private EntityManager hbsWebEntityManager;
#Override
public EntityManager resolveEntityManager() {
return hbsWebEntityManager;
}
}
Produces:
#ApplicationScoped
public class EntityManagerProducer {
#PersistenceUnit(unitName="HBS")
private EntityManagerFactory hbsEntityManager;
#PersistenceUnit(unitName="HBSWEB")
private EntityManagerFactory hbsWebEntityManager;
#Produces
#Hbs
protected EntityManager createHbsEntityManager() {
return hbsEntityManager.createEntityManager();
}
protected void closeHbsEntityManager(
#Disposes #Hbs EntityManager entityManager) {
if (entityManager.isOpen()) {
entityManager.close();
}
}
#Produces
#HbsWeb
protected EntityManager createHbsWebEntityManager() {
return hbsWebEntityManager.createEntityManager();
}
protected void closeHbsWebEntityManager(
#Disposes #HbsWeb EntityManager entityManager) {
if (entityManager.isOpen()) {
entityManager.close();
}
}
}
When I try to use the repository with #inject I get the follow error:
org.apache.deltaspike.data.impl.handler.QueryInvocationException: Exception calling Repository: [Repository=class co.com.compuhelmac.hbs.repository.UserRepository_$$_javassist_0,method=findByLoginEqual],exception=class org.jboss.weld.exceptions.AmbiguousResolutionException,message=WELD-001318 Cannot resolve an ambiguous dependency between [Producer Method [EntityManager] with qualifiers [#Hbs #Any] declared as [[BackedAnnotatedMethod] #Produces #Hbs protected co.com.compuhelmac.hbs.database.EntityManagerProducer.createHbsEntityManager()], Producer Method [EntityManager] with qualifiers [#HbsWeb #Any] declared as [[BackedAnnotatedMethod] #Produces #HbsWeb protected co.com.compuhelmac.hbs.database.EntityManagerProducer.createHbsWebEntityManager()]]
at org.apache.deltaspike.data.impl.handler.QueryHandler.invoke(QueryHandler.java:86)
at org.apache.deltaspike.partialbean.impl.PartialBeanAbstractMethodHandler.invoke(PartialBeanAbstractMethodHandler.java:44)
at org.apache.deltaspike.partialbean.impl.MethodHandlerProxy.invoke(MethodHandlerProxy.java:35)
at com.sun.proxy.$Proxy549.invoke(Unknown Source)
at co.com.compuhelmac.hbs.repository.UserRepository_$$_javassist_0.findByLoginEqual(UserRepository_$$_javassist_0.java)
at co.com.compuhelmac.hbs.security.HbsLoginEJB.login(HbsLoginEJB.java:46)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4695)
at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:630)
at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:582)
at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:46)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
Caused by: org.jboss.weld.exceptions.AmbiguousResolutionException: WELD-001318 Cannot resolve an ambiguous dependency between [Producer Method [EntityManager] with qualifiers [#Hbs #Any] declared as [[BackedAnnotatedMethod] #Produces #Hbs protected co.com.compuhelmac.hbs.database.EntityManagerProducer.createHbsEntityManager()], Producer Method [EntityManager] with qualifiers [#HbsWeb #Any] declared as [[BackedAnnotatedMethod] #Produces #HbsWeb protected co.com.compuhelmac.hbs.database.EntityManagerProducer.createHbsWebEntityManager()]]
at org.jboss.weld.manager.BeanManagerImpl.resolve(BeanManagerImpl.java:1154)
at org.jboss.weld.manager.BeanManagerImpl.getBean(BeanManagerImpl.java:798)
at org.jboss.weld.bean.builtin.InstanceImpl.get(InstanceImpl.java:79)
at org.apache.deltaspike.data.impl.handler.EntityManagerLookup.lookupFor(EntityManagerLookup.java:51)
at org.apache.deltaspike.data.impl.handler.QueryHandler.createContext(QueryHandler.java:97)
at org.apache.deltaspike.data.impl.handler.QueryHandler.invoke(QueryHandler.java:74)
Does anyone know why this error happens?

Going by your stacktrace
org.apache.deltaspike.data.impl.handler.EntityManagerLookup.lookupFor(EntityManagerLookup.java:51)
and taking a look at the sources of DeltaSpike 0.5, I'd say this is a bug in the 0.5 release, since the EntityManager obtained from the EntityManagerResolver is never used.
Try again with a DeltaSpike 0.6-SNAPSHOT - there are many improvements in the Data module, and this particular piece of code looks more correct now.

Your EM resolver is getting called, but the problem is when trying to inject to
#Inject
#HbsWeb
private EntityManager hbsWebEntityManager;
Due to a resolution problem between : createHbsWebEntityManager() and createHbsEntityManager()
How are the #HbsWeb and #Hbs defined? are they related?

Related

Still receiving BeanDefinitionOverrideException after setting overriding to true

When building my project, i am receiving errors for my test. I googled a little and found that everyone is talking about how spring requires setting the bean definition overriding to true. My properties has already set the bean overriding to true but still i am receiving this error. Does anyone know what am i missing?
Controller Test
#WebMvcTest(controllers = PermitController.class)
public class PermitControllerTest extends CrudControllerTest<Permit, PermitRepository> {
#TestConfiguration
static class Configuration {
#Bean
public PermitController permitController() {
return new PermitController();
}
}
#Autowired
private PermitController permitController;
#MockBean
private PermitRepository permitRepository;
#MockBean
private AccountRepository accountRepository;
#MockBean
private PocRepository pocRepository;
#MockBean
private DateslotRepository dateslotRepository;
#MockBean
private TimeslotRepository timeslotRepository;
#MockBean
private CoordinateRepository coordinateRepository;
// TODO: test invalid fields
/**
* Setup before unit tests are run.
*/
#Before
public void before() {
permitController.setRepository(permitRepository);
super.init(permitRepository);
super.setUrl(WebConfig.PERMIT + "/");
super.setEntities(TestEntities.getPermit(null), TestEntities.getPermit(TestEntities.ID1));
}
}
Error from test
Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'permitController' defined in com.example.permitservice.controller.PermitControllerTest$Configuration: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=permitControllerTest.Configuration; factoryMethodName=permitController; initMethodName=null; destroyMethodName=(inferred); defined in com.example.permitservice.controller.PermitControllerTest$Configuration] for bean 'permitController': There is already [Generic bean: class [com.example.permitservice.controller.PermitController]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [E:\workspace\gitpermitmanager\permitMgrService\build\classes\java\main\com\example\permitservice\controller\PermitController.class]] bound.
at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:894)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:274)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:141)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:117)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:327)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:232)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:691)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:528)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:127)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
... 50 more
Properties:
spring.profiles.active = development
spring.main.allow-bean-definition-overriding = true

A managed bean instance being injected using #ManagedProperty remains null

I have two classes of managed beans and use #ManagedProperty to try to access the second one but I get NullPointerException every time. What is the problem here?
#ManagedBean
#SessionScoped
public class EventCreateEditModel implements Serializable {
#ManagedProperty("#{eventCreateEditCostModel}")
private EventCreateEditCostModel eventCreateEditCostModel;
public void update() {
eventCreateEditCostModel.update();
}
public void setEventCreateEditCostModel(final EventCreateEditCostModel eventCreateEditCostModel) {
this.eventCreateEditCostModel = eventCreateEditCostModel;
}
public EventCreateEditCostModel getEventCreateEditCostModel() {
return eventCreateEditCostModel;
}
}
Here is my second class.
#ManagedBean
#SessionScoped
public class EventCreateEditCostModel implements Serializable {
public void update() {
System.out.println("IT works");
}
}
I try to get the first class to call the second class update using #ManagedProperty but all I get is NullPointerException, when I try to access the update from the first class. I do have setters and getters for the #ManagedProperty.
Here is the stack trace which points to the update method in class EventCreateEditModel (tried to paste the whole stack but this system will not format it so here are the key parts)
`Dec 24, 2015 2:02:57 PM com.sun.faces.lifecycle.InvokeApplicationPhase execute
WARNING: java.lang.NullPointerException
javax.el.ELException: java.lang.NullPointerException
at com.sun.el.parser.AstValue.invoke(AstValue.java:238)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
Caused by: java.lang.NullPointerException
at com.rem40.controller.EventCreateEditModel.update (EventCreateEditModel.java:116)
... 35 more
Dec 24, 2015 2:02:57 PM com.sun.faces.context.AjaxExceptionHandlerImpl handlePartialResponseError
SEVERE: java.lang.NullPointerException
at com.rem40.controller.EventCreateEditModel.update(EventCreateEditModel.java:116)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)`

Ambiguous dependencies when I added a producer class

I was reading/testing the following tutorial about CDI: [link].
And I got an exception when I added a producer class to the code.
Basically, there's an interface with a default implementation:
public interface ATMTransport {
public void communicateWithBank(byte[] datapacket);
}
#Default
public class StandardAtmTransport implements ATMTransport {
public void communicateWithBank(byte[] datapacket) {
System.out.println("communicating with bank via Standard transport");
}
}
Next, there's another class which injects the ATMTransport interface:
#Named("atm")
public class AutomatedTellerMachineImpl implements AutomatedTellerMachine {
#Inject
private ATMTransport transport;
public void deposit(BigDecimal bd) {
transport.communicateWithBank(null);
}
}
Everything is OK so far. So in the section about 'producers', they show a new class:
public class TransportFactory {
#Produces ATMTransport createTransport() {
System.out.println("ATMTransport created with producer");
return new StandardAtmTransport();
}
}
Then, by adding the producer class I got this exception:
WELD-001409: Ambiguous dependencies for type ATMTransport with qualifiers #Default
at injection point [BackedAnnotatedField] #Inject private AutomatedTellerMachineImpl.transport at AutomatedTellerMachineImpl.transport(AutomatedTellerMachineImpl.java:0)
Possible dependencies:
- Managed Bean [class StandardAtmTransport] with qualifiers [#Default #Any],
- Producer Method [ATMTransport] with qualifiers [#Any #Default] declared as [[BackedAnnotatedMethod] #Produces TransportFactory.createTransport()]
I solved the problem by using qualifiers, but I really don't know why.
My question is, why does the producer class cause that exception? (They didn't mention anything about it on their tutorial).
I really need a little explanation.
Based on the code you supplied, you ended up creating a default implementation of ATMTransport that is a managed bean. The exception is caused by having both beans available with the same injection targets. #Default is the qualifier added to all CDI beans. Basically, there is no need for the producer method since the one provided by the class definition by itself is the same.
I guess the bigger question - what were you trying to do with the producer method?

NullPointerException while trying to access #EJB bean in managed bean constructor

I've an EJB service.
#Stateless
public class SomeService {}
I'd like to inject this in a viewscoped bean and initialize with it:
#ManagedBean
#ViewScoped
public class ViewBean implements Serializable {
#EJB
private SomeService someService;
public ViewBean() {
System.out.println(someService.getEntity());
}
}
However, it throws the following exception:
com.sun.faces.mgbean.ManagedBeanCreationException: Cant instantiate class: com.example.ViewBean.
at com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:193)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:102)
at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:409)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:269)
at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
[snip]
Caused by: java.lang.NullPointerException
at com.example.ViewBean.<init>(ViewBean.java:42)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at java.lang.Class.newInstance0(Class.java:374)
at java.lang.Class.newInstance(Class.java:327)
at com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:188)
... 62 more
How is this caused and how can I solve it?
In other words, you're expecting that EJB injection works under the covers as follows:
ViewBean viewBean;
viewBean.someService = new SomeService(); // EJB injected, so that constructor can access it.
viewBean = new ViewBean(); // ViewBean constructed.
However, this is technically impossible. It's not possible to assign an instance variable when the instance isn't been constructed at all.
The canonical approach to perform a task based on injected dependencies directly after construction is to use a #PostConstruct annotated method.
So, to fix your concrete problem, just replace
public ViewBean() {
by
#PostConstruct
public void init() { // Note: Method name is fully free to your choice.
This way the process would under the covers be roughly as follows:
ViewBean viewBean;
viewBean = new ViewBean(); // ShiftBean constructed.
viewBean.someService = new SomeService(); // EJB injected.
viewBean.init(); // PostConstruct invoked.
Please note that the concrete problem has completely nothing to do with the view scope. You'd have had exactly the same problem when using a request, session or application scoped bean. This is thus another evidence that you have never actually excluded it from being the cause by testing using a different scope.

NullPointerException while trying to access #Inject bean in constructor

I've a session scoped bean:
#Named
#SessionScoped
public class SessionBean implements Serializable {
private String someProperty;
public String getSomeProperty() {
return someProperty;
}
}
I'd like to inject this in a request scoped bean and initialize with it:
#Named
#RequestScoped
public class RequestBean {
#Inject
private SessionBean sessionBean;
public RequestBean() {
System.out.println(sessionBean.getProperty());
}
}
However, it throws the following exception:
java.lang.NullPointerException
at com.example.RequestBean.<init>(RequestBean.java:42)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at org.jboss.weld.introspector.jlr.WeldConstructorImpl.newInstance(WeldConstructorImpl.java:206)
at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:117)
at org.jboss.weld.bean.ManagedBean.createInstance(ManagedBean.java:336)
at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget.produce(ManagedBean.java:200)
at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:292)
...
How is this caused and how can I solve it?
You're expecting that the injected dependency is available before the bean is constructed. You're expecting that it works like this:
RequestBean requestBean;
requestBean.sessionBean = sessionBean; // Injection.
requestBean = new RequestBean(); // Constructor invoked.
This is however not true and technically impossible. The dependencies are injected after construction.
RequestBean requestBean;
requestBean = new RequestBean(); // Constructor invoked.
requestBean.sessionBean = sessionBean; // Injection.
You should be using a #PostConstruct method instead if you intend to perform business logic based on injected dependencies directly after bean's construction.
Remove the constructor and add this method:
#PostConstruct
public void init() {
System.out.println(sessionBean.getSomeProperty());
}
BalusC's reply is correct, but is does reflect the assignment phase of a object creation, that did not run at this time. But anyway the CDI bean should be accessible if you grep it programatically via:
javax.enterprise.inject.spi.CDI.current().select(SessionBean.class).get()

Resources