NoSuchBeanDefinitionException EntityManagerFactory - import d'un context spring externe
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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.