multiple #Qualifier EJB injection - interface

i have 2 EJB implements same interface, i have some qualifier :
#java.lang.annotation.Documented
#java.lang.annotation.Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD, ElementType.TYPE,ElementType.FIELD})
#javax.inject.Qualifier
public #interface PayEseConnector {
}
and
#java.lang.annotation.Documented
#java.lang.annotation.Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD, ElementType.TYPE,ElementType.FIELD})
#javax.inject.Qualifier
public #interface MetrilioConnector {
}
example of EJB:
#Stateless
#PayEseConnector
#Local
public class PayEseServiceImpl implements IConnectorService {
or
#Stateless
#MetrilioConnector
#Local
public class MetrilioServiceImpl implements IConnectorService {
i inject one of those into a class:
public class TestResource {
#MetrilioConnector
#Inject
IConnectorService metrilioService;
and my error :
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type IConnectorService with qualifiers #MetrilioConnector
at injection point [UnbackedAnnotatedField] #MetrilioConnector #Inject com.real.hr.rest.TestResource.metrilioService
at com.real.hr.rest.TestResource.metrilioService(TestResource.java:0)
WELD-001475: The following beans match by type, but none have matching qualifiers:
- Session bean [class com.real.hr.services.MetrilioServiceImpl with qualifiers [#MetrilioConnector #Any]; local interfaces are [IConnectorService],
- Session bean [class com.real.hr.services.PayEseServiceImpl with qualifiers [#PayEseConnector #Any]; local interfaces are [IConnectorService]
what i am doing wrong?, with one #Qualifier it is working

Finally the example is OK the error was i renamed a package and dependency was still present so you can use this example to make simple Qualifier for EJB implements same interface, normally #Local is not mandatory...

Related

Using spring-retry #EnableRetry with spring-batch causes unexpected proxy

I am trying to make use of the spring-retry library in my batch job and on adding the #EnableRetry annotation to my #Configuration as documentation suggests my application is now failing because it appears a spring-batch library bean which is being #Autowired is being proxied.
#Configuration
#EnableBatchProcessing
#EnableRetry
#Import({SpringBatchConfiguration.class, School192ClientConfiguration.class })
public class SchoolJobConfiguration { .. }
Exception:
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'jobRegistry' is expected to be of type 'org.springframework.batch.core.configuration.JobRegistry' but was actually of type 'com.sun.proxy.$Proxy130'
I have added the following to a separate class:
#Retryable(value = School192ClientException.class, maxAttempts = 3, backoff = #Backoff(delay = 2000))
#Override
protected void doReadPage() {
My question is why is this bean (jobRegistry) being proxied? (I don't have much experience with AOP).
I am using spring-boot version 1.5.3.RELEASE.

how to inject the multiple bean in to single referenced variable dynamically using spring annotation

I have interface A.java and 3 classes which are implementing A.java interface named B.java, C.java and D.java. Now i am try to inject the bean like this.
interface A{}
#Component
#Scope("request")
class B implements A{
//......
}
#Component
#Scope("request")
class C implements A{
//.....
}
#Component
#Scope("request")
class D implements A{
}
class Implementation{
#Autowired
public A obj;
#Autowired
private BeanFactory beanFactory;
String[] beans = {"B","C","D"}; //actually these are coming from database in my case
for(String beanName : beans){
obj = (A)beanFactory.getBean(beanName);
....//calling some method of particular bean class
}
}
It is showing Error message something: "Unique bean not found: contains multiple beans["B","C","D"]".
If I am configuring these beans in XML file, it is working fine but I don't want to use xml config
How to solve this problem Using spring Annonantion??
It seems to me that the problem is with the Autowired annotation, because it'll do the injection by type, and the type of your variable is A, so It will be difficult to decide which bean to actually inject, B, C or D.
Try to use Resource annotation which decide to inject by name. Or instead just add Qualifier annotation.
Look here for further explanation:
Difference between #Qualifier and #Resource

#Autowired by constructor looks for beans by type. How to inject a bean by name to a constructor using autowired annotation

#Autowired by constructor looks for beans by type. How to inject a bean by name to a constructor using autowired annotation?
I have 2 beans of same type but I need to inject it to constructor of another same class based on the bean name. How do I do it?
XML:
<bean id="A" class="com.Check"/>
<bean id="B" class="com.Check"/>
Java:
Class C {
private Check check;
#Autowired
public C(Check check){
this.check = check
}
}
When I do this I get an exception telling me that I have 2 beans of same type check but it requires there to be just one bean of that type. How can I inject the bean with id="B" into this class C through constructor injection?
In my applicationContext.xml I have mentioned autowire="byType". I need to autowire byName only in this particular class rest all it needs to be autowired by Type only
You should use #Qualifier annotation with your target bean id for constructor parameter.
<bean id="A" class="com.Check"/>
<bean id="B" class="com.Check"/>
Class C {
private Check check;
#Autowired
public C(#Qualifier("A") Check check){ //<-- here you should provide your target bean id
this.check = check
}
}

Try to use EmbeddedId in Superclass

I have the following problem:
I have a base class (used as superclass) with a composite primary key. And now I'am trying to setup subclasses correctly from the base class, but this doesn't work! Could somebody help me? Thanks
Here are my classes:
BasePK.java
#Embeddable
public class BasePK implements Serializeable {
protected String base1;
protected Timestamp base2;
..
}
Base.java
#MappedSuperclass
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Base implements Serializeable {
#EmbeddedId
protected BasePK id;
..
}
SubClassA.java
#Entity
public class SubClassA extends Base implements Serializeable {
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="attrA")
protected List<SubClassB> attrsB;
protected String attrA1;
protected String attrA2;
..
}
SubClassB.java
#Entity
public class SubClassB extends Base implements Serializeable {
#ManyToOne(fetch=FetchType.LAZY)
private SubClassA attrA;
protected String attrB1;
protected String attrB2;
..
}
SubClassC.java
#Entity
public class SubClassC extends SubClassA implements Serializeable {
protected String attrC1;
protected String attrC2;
..
}
When I try to run the project, the following excetions are made:
[EL Info]: 2012-11-01 23:31:18.739--ServerSession(2063330336)--EclipseLink, version: Eclipse Persistence Services - 2.4.1.v20121003-ad44345
[EL Warning]: metadata: 2012-11-01 23:31:19.199--ServerSession(2063330336)--Reverting the lazy setting on the OneToOne or ManyToOne attribute [controlledObject] for the entity class [class logyourlife.entities.ChangeRecord] since weaving was not enabled or did not occur.
[EL Severe]: 2012-11-01 23:31:19.229--ServerSession(2063330336)--Exception [EclipseLink-0] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions:
---------------------------------------------------------
Exception [EclipseLink-48] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [SUBCLASSB.BASE1]. Only one may be defined as writable, all others must be specified read-only.
Mapping: org.eclipse.persistence.mappings.ManyToOneMapping[attrA]
Descriptor: RelationalDescriptor(test.entities.SubClassB --> [DatabaseTable(SUBCLASSB)])
Exception [EclipseLink-48] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [SUBCLASSB.BASE2]. Only one may be defined as writable, all others must be specified read-only.
Mapping: org.eclipse.persistence.mappings.ManyToOneMapping[attrA]
Descriptor: RelationalDescriptor(test.entities.SubClassB --> [DatabaseTable(SUBCLASSB)])
fyi: The equals and hashcode method are overwritten in all classes.
First of all, remove the #Inheritance annotation on Base. It doesn't serve any purpose.
Then, try to explicitely define join columns for the ManyToOne association. It seems EclipseLink uses the same column names by default both for the embedded ID fields and for the many-to-one association with SubClassA. See http://docs.oracle.com/javaee/6/api/javax/persistence/JoinColumn.html for an example of using this annotation.
Side note: composite IDs are both inefficient, and complex to handle. You should really consider using autogenerated, single-column IDs for all your entities. Everything would be much easier.

javax.inject.Qualifier Spring JavaConfig

I have the following code
The 2 javax.Inject Qualifiers
#Qualifier
#Target(value={ElementType.FIELD,ElementType.TYPE,ElementType.PARAMETER})
#Retention(RetentionPolicy.RUNTIME)
public #interface Hibernate {
--nothing goes here
}
#Qualifier
#Target(value={ElementType.FIELD,ElementType.TYPE,ElementType.PARAMETER})
#Retention(RetentionPolicy.RUNTIME)
public #interface Toplink{
--nothing goes here
}
I Qualify the repositories
#Named
#Hibernate
public class HibernateRepository implements IRepository{
-- some code
}
#Named
#Toplink
public class ToplinkRepository implements IRepository{
-- some code
}
These repositories are injected using javax.Inject
public class InvoiceService {
#Inject
//#Hibernate I alternate between the two to test
#Toplink
private IRepository iRepository;
public void saveInvoice(Invoice invoice){
iRepository.save(invoice);
}
using the following configuration class
#Configuration
public class Myconfig {
#Bean
public IRepository getHibernateRepository(){
return new HibernateRepository();
}
#Bean
public InvoiceService getInvoiceService(){
return new InvoiceService();
}
#Bean
public IRepository getToplinkRepository(){
return new ToplinkRepository();
}
}
This code works perfectly fine when I use the XML configuration , any idea how to get it working with javaConfig ?? Or is there something fundamentally wrong in my code ?? When used its throws the following exception
Exception in thread "main"
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'getInvoiceService': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private com.domain.IRepository
com.service.InvoiceService.iRepository; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
matching bean of type [com.domain.IRepository] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for
this dependency. Dependency annotations: {#javax.inject.Inject(),
#com.domain.Toplink()}
Thanks in anticipation.
In the case of #Bean methods, it's the return type that counts. Even though you may be returning a TopLinkRepository from one method, and a HibernateRepository from another, from the container's point of view, all it knows is that there are two beans of type IRepository, and therefore does not understand that one is #Toplink annotated and one is #Hibernate annotated.
You have several of choices here. The simplest, given your current configuration, would be to change the return types to make them more specific.
The second is to leave the return types generic, but move the #Toplink and #Hibernate qualifier annotations to the #Bean method level.
The third is to component-scan for the repository types instead of declaring them as #Bean methods.
The third approach is generally recommended, given that you're already using #Inject on the repository components, and have them marked with #Named. This makes them natural candidates for component-scanning in the first place. Check out the Javadoc for #ComponentScan to see how to do this in the #Configuration class world.