[Spring 2.5] Problème de création d'un service Générique IService<T>
bonjour,
Je me suis inspiré de cet article http://www.ibm.com/developerworks/ja...enericdao.html pour créer un DAO générique.
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
public interface IDAO<T> {
public T get(Long id);
public T getReference(Long id);
public void save(T t);
public void update(T t);
public void remove(T t); |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
@Repository
public abstract class AbstractDAOBean<T extends AbstractEntity> implements IDAO<T> {
private static final Logger log = Logger.getLogger(AbstractDAOBean.class);
@PersistenceContext(type = PersistenceContextType.EXTENDED)
protected EntityManager em;
private final Class<T> entityClass;
/**
* Default constructor.
*/
@SuppressWarnings("unchecked")
public AbstractDAOBean() {
this.entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
/**
* Returns the underlying Hibernate Session of the current EntityManager.
*
* @return the Hibernate Session.
*/
protected Session getSession() {
return (Session) em.getDelegate();
}
protected Class<T> getEntityClass() {
return entityClass;
}
public T get(Long id) {
return em.find(entityClass, id);
}
public T getReference(Long id) {
return em.getReference(entityClass, id);
}
public void save(T t) {
if (t.getId() == null) {
// new
em.persist(t);
}
else {
// update
em.merge(t);
}
log.debug(entityClass.getSimpleName() + "Saves");
}
public void update(T t) {
em.merge(t);
} |
Lorsque j'appelle toutes les classes fils de mon DAO générique depuis une seule classe service. Pas de problème tout marche parfaitement.
En revanche pour éviter de dupliquer les même fonctions de la couche services dans toutes les classes qui en hérite. J'ai voulu créer une classe Service Générique.
Cette interface << IService<T> >> liste toutes les fonctions CRUD dans mon IDAO.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
public interface IService<T> {
public T get(Long id);
public T getReference(Long id);
public void save(T t);
public void update(T t);
public void remove(T t);
} |
Une classe AbstractService générique implémente l"interface IService<T>
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
@Service
@Transactional
public abstract class AbstractServiceBean<T extends AbstractEntity> implements IService<T> {
// couche [dao]
public IDAO<T> dao;
public IDAO<T> getDao() {
return dao;
}
@Autowired
public void setDao(IDAO<T> dao) {
this.dao = dao;
}
private final Class<T> entityClass;
/**
* Default constructor.
*/
@SuppressWarnings("unchecked")
public AbstractServiceBean() {
this.entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
protected Class<T> getEntityClass() {
return entityClass;
}
public T get(Long id) {
return dao.get(id);
}
public T getReference(Long id) {
return dao.getReference(id);
}
public void save(T t) {
dao.save(t);
}
public void update(T t) {
dao.update(t);
}
public void remove(T t) {
dao.remove(t);
} |
Je me fait également injecter les différents DAO dans les différents services comme suit
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
@Service("RequestService")
@Transactional
public class RequestServiceBean extends AbstractServiceBean<Request> implements RequestService {
private static final Logger log = Logger.getLogger(RequestServiceBean.class);
// Inject couche [dao]
private RequestDao dao;
public RequestDao getDao() {
return dao;
}
@Autowired
public void setDao(RequestDao dao) {
this.dao = dao;
}
.... |
Lorsque je veut me faire injecter tous mes services lors de l'initialisation de l'application :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
@Autowired
private PDVService pdvService;
@Autowired
private InfosService infosService;
@Autowired
private RequestService requestService;
@Autowired
private PageService pageService;
@Autowired
private XmlFileService xmlFileService;
@Autowired
private TestService testService; |
Spring me génère cette erreur :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'InfosService': Autowiring of methods failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void fr.stime.service.AbstractServiceBean.setDao(fr.stime.dao.IDAO); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [fr.stime.dao.IDAO] is defined: expected single matching bean but found 6: [infosDaoBean, pageDaoBean, PDVDaoBean, requestDaoBean, testDaoBean, xmlFileDaoBean]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:256)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:998)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
at fr.stime.manager.Injector.init(Injector.java:10)
at fr.stime.test.InitDB.main(InitDB.java:49)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void fr.stime.service.AbstractServiceBean.setDao(fr.stime.dao.IDAO); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [fr.stime.dao.IDAO] is defined: expected single matching bean but found 6: [infosDaoBean, pageDaoBean, PDVDaoBean, requestDaoBean, testDaoBean, xmlFileDaoBean]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:543)
at org.springframework.beans.factory.annotation.InjectionMetadata.injectMethods(InjectionMetadata.java:117)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:253)
... 17 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [fr.stime.dao.IDAO] is defined: expected single matching bean but found 6: [infosDaoBean, pageDaoBean, PDVDaoBean, requestDaoBean, testDaoBean, xmlFileDaoBean]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:621)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:499)
... 19 more |
Il me dit que IDAO n'est pas un Bean unique ! je dois avoir une @Autowired en plus ou en moins dans un mauvais endroit !
Avez-vous une idée de quoi ce peut prevenir et comment résoudre ce problème ?
Merci par avance de votre aide.