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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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.