I'm trying to instantiate a generic class in Spring, but I get following exception:
Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class football.dao.jpa.GenericJpaDAO]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given:
This is the XML configuration for Spring container:
<bean id="clubDAO" class="football.dao.jpa.GenericJpaDAO">
<constructor-arg type="EntityManagerFactory" ref="entityManagerFactory"/>
<constructor-arg type="Class" value="football.model.entities.ClubEntity"/>
<constructor-arg type="String" value="ClubEntity"/>
</bean>
This is the generic class:
public class GenericJpaDAO <T extends HavingID> {
private EntityManager em;
private Class entityClass;
private String entityName;
public GenericJpaDAO( Class entityClass, String entityName,
EntityManagerFactory emFactory ) {
this.entityClass = entityClass;
this.entityName = entityName;
em = emFactory.createEntityManager();
}
@Transactional
public void create( T entity ) {
em.persist( entity );
}
// more methods
}
I'm not really sure what could be causing this. I would appreciate any ideas.
Here, @Bean instantiates two beans with ids the same as the method names and registers them within the BeanFactory (Spring container) interface. Next, we can initialize the Spring container and request any of the beans from the Spring container. This strategy also makes it simple to achieve dependency injection.
It will throw an error at runtime, as you can not define two Sspring beans of the same class with Singleton Scope in XML. (Very rare) The reference check will return true, as the container maintains one object. Both bean definitions will return the same object, so the memory location would be the same.
Step 1: Define beans by providing some names to them. Step 2: Access specific beans via @Qualifier annotation. @Autowired @Qualifier("krishna") private Employee emp1; @Autowired @Qualifier("ram") private Employee emp2; Find the below working example.
Declaring a bean. To declare a bean, simply annotate a method with the @Bean annotation. When JavaConfig encounters such a method, it will execute that method and register the return value as a bean within a BeanFactory .
This problem is not related to generics, it's a limitation of Spring AOP.
If aspects (including @Transactional
aspect) are applied to the class using CGLIB proxy (this happens if target class doesn't implement any interfaces or if AOP is configured with proxy-target-class = "true"
), no-argument constructor is required:
public class GenericJpaDAO <T extends HavingID> {
...
public GenericJpaDAO() {}
public GenericJpaDAO( Class entityClass, String entityName,
EntityManagerFactory emFactory ) { ... }
...
}
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With