Bonjour,

Je travaille sur un projet basé sur JPA avec hibernate comme implémentation.
J'ai créé deux projets : data-access (entités, dao) et business-services (services métier). Ce dernier importe bien entendu le projet data-access via maven (j'ai utilisé maven dans les deux projets).

Voici l'arborescence de mes projets :

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
data-access 
       | - src 
            | - main
            |        | - java [...]
            |               | - resources
            |                      | - com
            |                      |      | - masociete
            |                      |                  | - monprojet
            |                      |                            | - common
            |                      |                                    | - dataApplicationContext.xml
            |                      |                                    | - db.properties
            |                      | - META-INF
            |                      |           | - persistence.xml
            |                      | - log4j.properties
            | - test
            |     | - java [...]
            |     | - resources
            |             | - com
            |             |      | - masociete
            |             |              | - monprojet
            |             |                        | - common
            |             |                                   | - dataApplicationContextTest.xml
            |             |                                   | - dbTest.properties
            |             | - META-INF
            |                        | - persistence.xml
 
business-services
       | - src 
             | - main
             |      | - java [...]
             |      | - resources
             |                | - META-INF
             |                           | - spring
             |                                   | - businessApplicationContext.xml
             | - test
             |     | - java [...]
             |     | - resources
                            | - businessApplicationContextTests.xml
Projet Data-Access

dataApplicationContext.xml :

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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
 http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-3.0.xsd  
 http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
 http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 
    <!-- holding properties for database connectivity / -->
    <context:property-placeholder
        location="classpath*:/com/masociete/monprojet/common/db.properties" />
    <!-- enabling annotation driven configuration / -->
    <context:annotation-config />
    <context:component-scan base-package="com.masociete.monprojet.common" />
    <tx:annotation-driven transaction-manager="transactionManager" />
 
    <bean
        class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
 
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        p:driverClassName="${db.driverClassName}" p:url="${db.url}"
        p:password="${db.password}" p:username="${db.username}" />
 
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
        p:entityManagerFactory-ref="entityManagerFactory" />
 
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter">
        <property name="loadTimeWeaver">
            <bean
                class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property>
        <property name="persistenceUnitName" value="MonProjetPU"></property>
        <property name="persistenceXmlLocation" value="META-INF/persistence.xml" />
    </bean>
 
    <bean id="jpaAdapter"
        class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
        p:database="${jpa.database}" p:showSql="${jpa.showSql}" />
</beans>
db.properties :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
db.driverClassName=org.postgresql.Driver
db.url=jdbc:postgresql://localhost:5432/mabasededonnees
db.username=monutilisateur
db.password=monmotdepasse
jpa.database=POSTGRESQL
jpa.showSql=true
persistence.xml (src-main-resources-META-INF) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence">
 
    <persistence-unit name="MonProjetPU" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>com.masociete.monprojet.common.domain.User</class>
        <class>com.masociete.monprojet.common.domain.Client</class>
        <properties>
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>
</persistence>


dataApplicationContextTest.xml :

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
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
 http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-3.0.xsd  
 http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
 http://www.springframework.org/schema/aop  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 
    <!-- holding properties for database connectivity / -->
    <context:property-placeholder
        location="classpath*:/com/masociete/monprojet/common/dbTest.properties" />
    <!-- enabling annotation driven configuration / -->
    <context:annotation-config />
    <context:component-scan base-package="com.masociete.monprojet.common" />
    <tx:annotation-driven transaction-manager="transactionManager" />
 
    <bean
        class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
 
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        p:driverClassName="${db.driverClassName}" p:url="${db.url}"
        p:password="${db.password}" p:username="${db.username}" />
 
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
        p:entityManagerFactory-ref="entityManagerFactory" />
 
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter">
        <property name="loadTimeWeaver">
            <bean
                class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property>
        <property name="persistenceUnitName" value="MonProjetTestPU"></property>
        <property name="persistenceXmlLocation" value="META-INF/persistence.xml" />
    </bean>
 
    <bean id="jpaAdapter"
        class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
        p:database="${jpa.database}" p:showSql="${jpa.showSql}" />
 
</beans>


dbTest.properties :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
db.driverClassName=org.hsqldb.jdbcDriver
db.url=jdbc:hsqldb:mem:dataBaseTest
db.username=sa
db.password=
jpa.database=HSQL
jpa.showSql=true
persistence.xml (test - resources - META-INF) :
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
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence">
 
    <persistence-unit name="MonProjetTestPU"
        transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>com.masociete.monprojet.common.domain.User</class>
        <class>com.masociete.monprojet.common.domain.Client</class>
        <properties>
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>
</persistence>
Projet Business-Services

businessApplicationContext.xml :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
    <description>Business Services Context Configuration</description>
 
    <context:component-scan base-package="com.masociete.monprojet.business" />
    <context:component-scan base-package="com.masociete.monprojet.common.dao" />
</beans>
businessApplicationContextTests :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
    <description>Business Services Context Configuration</description>
    <import resource="classpath*:/com/masociete/monprojet/common/dataApplicationContextTest.xml" />
 
 
    <context:component-scan base-package="com.masociete.monprojet.business" />
    <context:component-scan base-package="com.masociete.monprojet.common.dao" />
</beans>
J'ai une entité client et une entité user. Un 'user' peut appartenir à un ou plusieurs clients (un client étant une société). J'ai écris les dao UserDao et ClientDao. En exécutant des tests unitaires dans data-access, je n'ai aucun problème. Tout fonctionne.
Par contre, quand je fais exactement le même test en utilisant un service qui fait appel à un dao, là j'ai cette exception :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
java.lang.IllegalStateException: Failed to load ApplicationContext
[...]
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 0
Le problème, je pense, est que j'importe le contextConfiguration de la couche dao dans la couche de services métier. Et, je pense que je ne le fais pas correctement...
Savez-vous comment je pourrais régler ce problème ?

PS : les dao possèdent l'annotation @Repository et les services @Service @Transactional
Voici la classe de test dans business-services :
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
@ContextConfiguration(locations = {"/businessApplicationContextTests.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class UserServiceTest extends AbstractTransactionalJUnit4SpringContextTests {
 
    @Autowired
    private IUserService userService;
    @Autowired
    private IUserDao userDao;
    @Autowired
    private IClientDao clientDao;
 
    @Before
    public void setUp() {
        Client client = InitBusinessHelper.createClient([plusieurs parametres...]);
        clientDao.persist(client);
        User user = InitBusinessHelper.createUser(client, [plusieurs parametres...]);
        userDao.persist(user);
    }
 
    @Test
    public void testCountAllService() {
        int nb = userService.countAll();
        assertEquals(1, nb);
    }
 
}
Merci beaucoup.