I am using Spring 3 and Hibernate 4
I have the following class structure
public interface GenericDAO<T> {
public void create(T entity);
public void update(T entity);
public void delete(T entity);
}
DAO class
public interface EmployeeDAO extends GenericDAO<Employee> {
public void findEmployee(EmployeeQueryData data);
}
DAO Implementation class
#Repository("employeeDAO")
public abstract class EmployeeDAOImpl implements EmployeeDAO {
protected EntityManager entityManager;
#Override
public void findEmployee(EmployeeQueryData data) {
...... code
}
The problem I am facing is when I try to deploy, I am getting the following exception.
If I remove abstract from EmployeeDAOImpl and remove extends GenericDAO<Employee> from EmployeeDAO then application gets deployed without errors. So it is not possible to have abstract class for EmployeeDAOImpl or I have need to implement all methods of GenericDAO in DAO implementation without abstract?
Error creating bean with
name 'employeeService': Injection of autowired dependencies failed; \
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: test.dao.EmployeeDAO
test.service.EmployeeServiceImpl.employeeDAO; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No matching bean of type [test.dao.EmployeeDAO] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for
this dependency. Dependency annotations:
{#javax.inject.Inject()}.
Edit 1
GenericDAOImpl
public class GenericDAOImpl<T> implements GenericDAO<T> {
public void create(T entity) {
}
public void update(T entity) {
}
public void delete(T entity) {
}
EmployeeDAOImpl
public class EmployeeDAOImpl extends GenericDAOImpl<Employee> implements EmployeeDAO {
Java (and consequently Spring) cannot create instances of abstract classes: every method must have an implementation before Java will let you create an instance, otherwise you would get a runtime error when you tried to call the method. You need to remove "abstract" from EmployeeDAOImpl and implement the methods inherited from GenericDAO.
Why do you want to declare a class implementation as abstract? Conceptually it's a contradiction. Obviously Spring cannot instantiate it and fails.
Confirm if your EmployeeDAOImpl or other annotated class packages are mentioned in spring context xml in following tag. Unless this is done, annotations won't get read and will not be initialized.
<context:component-scan base-package="com.app.service" />
Related
I am trying to implement as of enterprise level, there they have folders like Repository,Service,ServiceImpl
In Services they have interface with method declaration
In ServiceImpl they have class implementing the interface of services
In Repository they have all Repository interfaces
BeanInjection is a class where we have all repositories and service classes and interfaces with
#Autowired annotation.
When I tried to implement "#Autowired" to service class getting this Error.
Tried this no help link
Tried this no help but getting loop error link
Controller.java
public class SessionController extends BeanInjectionService {
#GetMapping
public ResponseEntity<List<Session>> list(){
LOGGER.info("Request received to view the sessions");
List<Session> sessions = sessionService.findAll();
LOGGER.info("Successfully fetched all the sessions");
return new ResponseEntity<>(sessions, HttpStatus.OK);
}
SessionService.java(Interface)
public interface SessionService {
List<Session> findAll();
}
SessionServiceImpl.java(Class)
public class SessionServiceImpl extends BeanInjectionService implements SessionService {
#Override
public List<Session> findAll(){
return sessionRepository.findAll();
}
BeanInjectionService.java(Class)
public class BeanInjectionService {
#Autowired
public SessionRepository sessionRepository;
**// Error Showing here while starting application
// Consider defining a bean of type 'com.example.conferencedemo.services.SessionService' in your configuration.**
#Autowired
public SessionService sessionService;
#Autowired
public SpeakerRepository speakerRepository;
#Autowired
public SpeakerService speakerService;
}
SessionRepository.java(Interface)
public interface SessionRepository extends JpaRepository<Session,Long> {
}
Thanks in advance
I find using BeanInjectionService a little weird, but I'll answer around it.
Unless you add #Service on SessionServiceImpl, you can't autowire it.
Circular dependency - If you do step 1, it will create a circular dependency because SessionServiceImpl needs its superclass object(BeanInjectionService) to be created first. But BeanInjectionService cannot be created unless it finds an object of SessionServiceImpl.
To break the circular dependency, you have only one option. Don't extend BeanInjectionService. Rather, autowire SessionRepository directly into SessionServiceImpl.
#Service
public class SessionServiceImpl implements SessionService {
#Autowired
private SessionRepository sessionRepository;
#Override
public List<Session> findAll(){
return sessionRepository.findAll();
}
}
Let's say that i have two Classes: Subject and Client, Subject is base-class.
#Entity
public class Client extends Subject
Now i want to add customized Jpa base interface, so methods will be accessible in subinterfaces:
#NoRepositoryBean
public interface SubjectRepository <T extends Subject> extends
JpaRepository<T, Long>, CustomSubjectRepository<T> {}
CustomSubjectRepository looks like:
public interface CustomSubjectRepository<T extends Subject> {
void saveEncrypted(T subject);
}
I need implementation so i declare class:
#Repository
#Transactional
public class CustomSubjectRepositoryImpl<T extends Subject> implements
CustomSubjectRepository<T> {
#PersistenceContext
private EntityManager entityManager;
#Override
public void saveEncrypted(T subject) {
//implementation
}
}
Then wanted to create ClientRepository and inherit from SubjectRepository to have access to saveEncrypted method.
#Repository
public interface ClientRepository extends SubjectRepository<Client> {
}
But when it comes to compile i get:
Error creating bean with name 'clientRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract void com.path.repositories.CustomSubjectRepository.saveEncrypted(com.path.models.Subject)! No property saveEncrypted found for type Client!
You are extending the interface, this way Spring will try to create a query named saveEncrypted instead of using the customized method.
I believe the best solution is to extend the class CustomSubjectRepositoryImpl.
#Repository
public class ClientRepository extends CustomSubjectRepositoryImpl<Client> {
}
I use spring-data-jpa to access my data. I need a way to detach an Object and store it as a new database row. My approach is currently to add a detach method to the repository, but for that, I need a EntityManager. And I haven't found a (nice) way of obtaining it... Any ideas?
#Repository
public interface InteractionRepository
extends JpaRepository<Interaction, Long>,
DetatchableItemRepository{}
public interface DetatchableItemRepository {
void detach(Interaction clone);
}
public class DetatchableItemRepositoryImpl implements DetatchableItemRepository {
#Autowired
EntityManager em;
public void detach(Interaction clone) {
em.detach(clone);
clone.id=null;
em.persist(clone);
}
}
However, spring dies with this error:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'interactionRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property detach found for type Interaction!
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property detach found for type Interaction!
you use wrong name convention for custom repository , try this :
public interface DetatchableItemRepositoryCustom {
void detach(Interaction clone);
}
public interface DetatchableItemRepository extends JpaRepository<Interaction, Long>,
DetatchableItemRepositoryCustom {
}
public class DetatchableItemRepositoryImpl implements DetatchableItemRepositoryCustom {
}
spring data use name convention for custom repository and main repository.(see about name Adding custom behavior to single repositories)
If you have some SomeRepository , that extends some base spring data repository , and want to add custom behavior then it should be like :
interface SomeRepositoryCustom{
someMethod();
}
//XXXRepository - any base spring data repository
interface SomeRepository extends<T ,ID> extend XXXRepository , SomeRepositoryCustom {
.......
}
public class ARepositoryImpl implement SomeRepositoryCustom{
#Overide
someMethod(){
....
}
This question already has an answer here:
What is a NoSuchBeanDefinitionException and how do I fix it?
(1 answer)
Closed 6 years ago.
I stack with above mentioned exception and really don't understate why it is appeared. I am using spring boot and declare bean through the annotation.
Application is executed by this class:
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
My problem bean has the following declaration:
#Service
public class OrderSvc extends AbstractService implements DAOService {
I try to put it in the following bean:
#RestController
public class OrderController {
#Autowired
CarSvc carSvc;
#Autowired
OrderSvc orderSvc;
and the exception is appeared: Could not autowire field: biz.Services.OrderSvc biz.controllers.rest.administrator.OrderController.orderSvc; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [biz.Services.OrderSvc] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
I have also CarSvc bean that is located at the same package as OrderSvc and extends the same classes but there are no problems with it injection
#Service
public class CarSvc extends AbstractService implements DAOService<Car> {
Do you have any ideas why this exception appears ?
Spring creates proxies for classes that declare #Transactional, so that it is able to add the transactional behaviour and intercepted calls to your object. If the bean extends any interface Spring is going to create a Dynamic Proxy using the JDK Reflection API and this can only be done by interface. The proxy is a new object implementing the same interface. So your target bean is not your implementation but a proxy. That is why you were getting a non qualify bean exception.
CGLIB, on the other hand, can create a proxy by subclassing.
So, to get it working, you need to change your bean type to the interface or you can configure cglib using #EnableTransactionManagement(proxyTargetClass = true).
Try to to autowire your beans using interfaces rather than implementations :
#RestController
public class OrderController {
#Autowired
#Qualifier("carSvc")
DAOService carSvc;
#Autowired
#Qualifier("orderSvc")
DAOService orderSvc;
}
Edit : But before that you have to give names to your services :
#Service("carSvc")
public class CarSvc extends AbstractService implements DAOService<Car> {}
#Service("orderSvc")
public class OrderSvc extends AbstractService implements DAOService<Order> {}
What's going on here is that Spring generate proxies of your services based on the CarSvc, OrderSvc and implement the DAOService but does not extend the CarSvc, OrderSvc.
//somthing like this
class CarSvcProxy implement DAOService {
public Object getOrder(Long id) {
try {
// ...
txManager.commit();
} catch (Exception ex) {
txManager.rollback();
}
}
}
#RestController
public class OrderController {
//So when you do this :
#Autowired
CarSvc carSvc;
//it's somehow like if you did :
CarSvc carSvc = new CarSvcProxy(); //carSvc != CarSvcProxy
//But this will work :
DAOService carSvc = new CarSvcProxy(); //because CarSvcProxy implement DAOService
}
I found the code which leads to exception but I really don't undestand why.
In my OrderSvc there is the following method:
#Transactional(readOnly = true)
public Object getOrder(Long id) {
final Order order = getDAO().findOne(id);
OrderDTO orderDTO = modelMapper.map(order, OrderDTO.class);
return orderDTO;
}
So if the annotation #Transactional(readOnly = true) was excluded the application can be excecuted without problem... Do you have any ideas why this annotation lead to NoSuchBeanDefinitionException ?
I use Spring data jpa and I am trying to add custom behaviour to all repositories as described here:
http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/#repositories.custom-behaviour-for-all-repositories
I encountered several issues:
-First, there is no such method as getDomainClass in the RepositoryMetadata class as described in the Spring documentation (see below):
protected Object getTargetRepository(RepositoryMetadata metadata) {
return new MyRepositoryImpl<T, I>((Class<T>) metadata.getDomainClass(), entityManager);
}
I used the following method instead: getDomainType() Is this right?
-Second my application throws exceptions when tomcat starts. Here is the full stack trace:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'globalRepositoryImpl' defined in file [E:\users\jumartin\dev_sts\.metadata\.plugins\org.eclipse.wst.server.core\
tmp0\wtpwebapps\SuiviTRC\WEB-INF\classes\trc\suivi\repository\GlobalRepositoryImpl.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could
not instantiate bean class [trc.suivi.repository.GlobalRepositoryImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: trc.suivi.repository.GlobalRepositoryImpl.<i
nit>()
Here is my custom global repository code:
public class GlobalRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements GlobalRepository<T, ID> {
private EntityManager em;
public GlobalRepositoryImpl(Class<T> domainClass, EntityManager em) {
super(domainClass, em);
this.em = em;
}
public void sharedCustomMethod(ID id) {
}
}
Here is my xml config:
<repositories base-package="trc.suivi.repository" factory-class="trc.suivi.repository.GlobalRepositoryFactoryBean">
<repository id="pliRepository" />
<repository id="globalRepository" />
</repositories>
I was not able to find any other sample on the web. Can anyone please help?
I have made a full example of how to add custom behaviour to all repositories.
http://borislam.blogspot.hk/2012/07/customizing-spring-data-jpa-repository.html
You could add features of different JPA implementation (e.g. hibernate, openJPA) to your base repository. I have made another tutorial on that.
http://borislam.blogspot.hk/2012/07/adding-hibernate-native-sql-features.html
I finally got some help and was able to get my repository to work by using the #NoRepositoryBean annotation on the intermediate interface.
Further info is available here: http://forum.springsource.org/showthread.php?128536-Several-issues-with-quot-adding-custom-behaviour-to-all-repositories-quot-in-spring-data-jpa
As of Spring Data JPA 1.9.M1 it's become easier to add custom methods to all repositories managed by Spring Data. This example has all the details.
In your case the example would look like:
1) Configuration
#Configuration
#EnableAutoConfiguration
#EnableJpaRepositories(repositoryBaseClass = GlobalRepositoryImpl.class)
class CustomRepositoryConfig {}
2) Custom base repository:
public class GlobalRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements GlobalRepository<ID> {
public GlobalRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
}
#Override
public void sharedCustomMethod(ID id) {
}
}
3) Some repository:
public interface SomeRepository extends GlobalRepository<User, Long> {}
Of course GlobalRepository still needs to be annotated with #NoRepositoryBean