J'utilise Spring-boot, donc une guerre déployée dans Tomcat 7. Lorsque je démarre l'application, j'obtiens ce qui suit:
Dec 30, 2013 7:41:06 PM org.Apache.catalina.core.ApplicationContext log
INFO: Initializing Spring FrameworkServlet 'dispatcherServlet'
2013-12-30 19:41:06 INFO DispatcherServlet:461 - FrameworkServlet 'dispatcherServlet': initialization started
2013-12-30 19:41:06 INFO SimpleUrlHandlerMapping:315 - Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2013-12-30 19:41:06 INFO RequestMappingHandlerMapping:181 - Mapped "{[/user],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public com.cloudfordev.controlpanel.orm.User com.cloudfordev.controlpanel.GetController.getUser(int)
2013-12-30 19:41:07 INFO SimpleUrlHandlerMapping:315 - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2013-12-30 19:41:07 INFO SimpleUrlHandlerMapping:315 - Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2013-12-30 19:41:08 INFO DispatcherServlet:480 - FrameworkServlet 'dispatcherServlet': initialization completed in 1957 ms
Dec 30, 2013 7:41:08 PM org.Apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
Dec 30, 2013 7:41:08 PM org.Apache.Tomcat.util.net.NioSelectorPool getSharedSelector
INFO: Using a shared selector for servlet write/read
Dec 30, 2013 7:41:08 PM org.Apache.coyote.AbstractProtocol stop
INFO: Stopping ProtocolHandler ["http-nio-8080"]
Dec 30, 2013 7:41:08 PM org.Apache.coyote.AbstractProtocol pause
INFO: Pausing ProtocolHandler ["http-nio-8080"]
Dec 30, 2013 7:41:08 PM org.Apache.catalina.core.StandardService stopInternal
INFO: Stopping service Tomcat
Dec 30, 2013 7:41:08 PM org.Apache.coyote.AbstractProtocol stop
INFO: Stopping ProtocolHandler ["http-nio-8080"]
Dec 30, 2013 7:41:08 PM org.Apache.coyote.AbstractProtocol destroy
INFO: Destroying ProtocolHandler ["http-nio-8080"]
2013-12-30 19:41:08 INFO AutoConfigurationReportLoggingInitializer$AutoConfigurationReportLogger:108 -
=========================
AUTO-CONFIGURATION REPORT
=========================
Positive matches:
-----------------
MessageSourceAutoConfiguration
- @ConditionalOnMissingBean (types: org.springframework.context.MessageSource; SearchStrategy: all) found no beans (OnBeanCondition)
PropertyPlaceholderAutoConfiguration#propertySourcesPlaceholderConfigurer
- @ConditionalOnMissingBean (types: org.springframework.context.support.PropertySourcesPlaceholderConfigurer; SearchStrategy: current) found no beans (OnBeanCondition)
DataSourceAutoConfiguration
- @ConditionalOnClass classes found: org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition)
- @ConditionalOnClass classes found: org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType (OnClassCondition)
DataSourceTransactionManagerAutoConfiguration
- @ConditionalOnClass classes found: org.springframework.jdbc.core.JdbcTemplate,org.springframework.transaction.PlatformTransactionManager (OnClassCondition)
- @ConditionalOnClass classes found: org.springframework.jdbc.core.JdbcTemplate,org.springframework.transaction.PlatformTransactionManager (OnClassCondition)
JpaBaseConfiguration.JpaWebConfiguration
- found web application StandardServletEnvironment (OnWebApplicationCondition)
- SpEL expression on org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration$JpaWebConfiguration: #{true} (OnExpressionCondition)
DispatcherServletAutoConfiguration
- found web application StandardServletEnvironment (OnWebApplicationCondition)
- @ConditionalOnClass classes found: org.springframework.web.servlet.DispatcherServlet (OnClassCondition)
- found web application StandardServletEnvironment (OnWebApplicationCondition)
- @ConditionalOnClass classes found: org.springframework.web.servlet.DispatcherServlet (OnClassCondition)
- @ConditionalOnBean (types: org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; SearchStrategy: all) found the following [tomcatEmbeddedServletContainerFactory] (OnBeanCondition)
DispatcherServletAutoConfiguration#dispatcherServlet
- no DispatcherServlet found (DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition)
EmbeddedServletContainerAutoConfiguration
- found web application StandardServletEnvironment (OnWebApplicationCondition)
- found web application StandardServletEnvironment (OnWebApplicationCondition)
EmbeddedServletContainerAutoConfiguration.EmbeddedTomcat
- @ConditionalOnClass classes found: javax.servlet.Servlet,org.Apache.catalina.startup.Tomcat (OnClassCondition)
- @ConditionalOnClass classes found: javax.servlet.Servlet,org.Apache.catalina.startup.Tomcat (OnClassCondition)
- @ConditionalOnMissingBean (types: org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; SearchStrategy: current) found no beans (OnBeanCondition)
ServerPropertiesAutoConfiguration#serverProperties
- @ConditionalOnMissingBean (types: org.springframework.boot.context.embedded.properties.ServerProperties; SearchStrategy: all) found no beans (OnBeanCondition)
WebMvcAutoConfiguration
- found web application StandardServletEnvironment (OnWebApplicationCondition)
- @ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.servlet.DispatcherServlet,org.springframework.web.servlet.config.annota
tion.WebMvcConfigurerAdapter (OnClassCondition)
- found web application StandardServletEnvironment (OnWebApplicationCondition)
- @ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.servlet.DispatcherServlet,org.springframework.web.servlet.config.annota
tion.WebMvcConfigurerAdapter (OnClassCondition)
- @ConditionalOnMissingBean (types: org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; SearchStrategy: all) found no beans (OnBeanCondition)
WebMvcAutoConfiguration#hiddenHttpMethodFilter
- @ConditionalOnMissingBean (types: org.springframework.web.filter.HiddenHttpMethodFilter; SearchStrategy: all) found no beans (OnBeanCondition)
WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#defaultViewResolver
- @ConditionalOnMissingBean (types: org.springframework.web.servlet.view.InternalResourceViewResolver; SearchStrategy: all) found no beans (OnBeanCondition)
Negative matches:
-----------------
RabbitAutoConfiguration
- required @ConditionalOnClass classes not found: org.springframework.amqp.rabbit.core.RabbitTemplate,com.rabbitmq.client.Channel (OnClassCondition)
AopAutoConfiguration
- required @ConditionalOnClass classes not found: org.aspectj.lang.annotation.Aspect,org.aspectj.lang.reflect.Advice (OnClassCondition)
BatchAutoConfiguration
- required @ConditionalOnClass classes not found: org.springframework.batch.core.launch.JobLauncher (OnClassCondition)
JpaRepositoriesAutoConfiguration
- required @ConditionalOnClass classes not found: org.springframework.data.jpa.repository.JpaRepository (OnClassCondition)
MongoRepositoriesAutoConfiguration
- required @ConditionalOnClass classes not found: com.mongodb.Mongo,org.springframework.data.mongodb.repository.MongoRepository (OnClassCondition)
DataSourceAutoConfiguration.DbcpConfiguration
- org.Apache.commons.dbcp.BasicDataSource DataSource class not found (DataSourceAutoConfiguration.BasicDatabaseCondition)
DataSourceAutoConfiguration.EmbeddedConfiguration
- no embedded database detected (DataSourceAutoConfiguration.EmbeddedDatabaseCondition)
DataSourceAutoConfiguration.JdbcTemplateConfiguration
- no existing bean configured database (DataSourceAutoConfiguration.DatabaseCondition)
DataSourceAutoConfiguration.TomcatConfiguration
- org.Apache.Tomcat.jdbc.pool.DataSource DataSource class not found (DataSourceAutoConfiguration.TomcatDatabaseCondition)
DataSourceTransactionManagerAutoConfiguration#transactionManager
- @ConditionalOnBean (types: javax.sql.DataSource; SearchStrategy: all) found no beans (OnBeanCondition)
JmsTemplateAutoConfiguration
- required @ConditionalOnClass classes not found: org.springframework.jms.core.JmsTemplate,javax.jms.ConnectionFactory (OnClassCondition)
DeviceResolverAutoConfiguration
- required @ConditionalOnClass classes not found: org.springframework.mobile.device.DeviceResolverHandlerInterceptor,org.springframework.mobile.device.DeviceHandlerMethodArgumentResolver (OnClassCondition)
HibernateJpaAutoConfiguration
- @ConditionalOnClass classes found: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,org.springframework.transaction.annotation.EnableTransactionManagement,javax.persistence.EntityManager,org.hibernate.ejb.HibernateEntityManager (OnClassCondition)
- @ConditionalOnClass classes found: org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,org.springframework.transaction.annotation.EnableTransactionManagement,javax.persistence.EntityManager,org.hibernate.ejb.HibernateEntityManager (OnClassCondition)
- @ConditionalOnBean (types: javax.sql.DataSource; SearchStrategy: all) found no beans (OnBeanCondition)
ReactorAutoConfiguration
- required @ConditionalOnClass classes not found: reactor.spring.context.config.EnableReactor (OnClassCondition)
ThymeleafAutoConfiguration
- required @ConditionalOnClass classes not found: org.thymeleaf.spring3.SpringTemplateEngine (OnClassCondition)
EmbeddedServletContainerAutoConfiguration.EmbeddedJetty
- required @ConditionalOnClass classes not found: org.Eclipse.jetty.server.Server,org.Eclipse.jetty.util.Loader (OnClassCondition)
MultipartAutoConfiguration
- @ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.multipart.support.StandardServletMultipartResolver (OnClassCondition)
- @ConditionalOnClass classes found: javax.servlet.Servlet,org.springframework.web.multipart.support.StandardServletMultipartResolver (OnClassCondition)
- @ConditionalOnBean (types: javax.servlet.MultipartConfigElement; SearchStrategy: all) found no beans (OnBeanCondition)
WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#beanNameViewResolver
- @ConditionalOnBean (types: org.springframework.web.servlet.View; SearchStrategy: all) found no beans (OnBeanCondition)
WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#viewResolver
- @ConditionalOnBean (types: org.springframework.web.servlet.View; SearchStrategy: all) found no beans (OnBeanCondition)
WebSocketAutoConfiguration
- required @ConditionalOnClass classes not found: org.springframework.web.socket.WebSocketHandler (OnClassCondition)
Java.lang.reflect.InvocationTargetException
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at Java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.Java:53)
at Java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDao': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.Java:356)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.Java:1180)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.Java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.Java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.Java:300)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.Java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.Java:296)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.Java:195)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.Java:660)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.Java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.Java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.Java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.Java:552)
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:293)
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:749)
at org.springframework.boot.SpringApplication.run(SpringApplication.Java:738)
at com.cloudfordev.controlpanel.Application.main(Application.Java:14)
... 6 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findDefaultEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.Java:559)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.Java:515)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.Java:682)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.getResourceToInject(PersistenceAnnotationBeanPostProcessor.Java:655)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.Java:150)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.Java:87)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.Java:353)
... 22 more
Voici comment démarre mon application:
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Lorsque mon contrôleur Spring gère la connexion:
@Controller
public class GetController {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
@RequestMapping(value = "/user", method = RequestMethod.GET)
public @ResponseBody User getUser(@RequestParam(value="id", required=true) int id) {
User user = null;
user = userService.getUser(id);
return user;
}
}
Il fait un getUser sur le userService:
@Component
public class UserService {
private UserDAO UserDao;
public UserDAO getUserDao() {
return UserDao;
}
@Autowired
public void setUserDao(UserDAO UserDao) {
this.UserDao = UserDao;
}
public User getUser(int id) {
return getUserDao().load(id);
}
}
Qui utilise userDao pour trouver l'entité:
@Repository("userDao")
@Transactional(propagation=Propagation.REQUIRED)
public class UserDAO {
@PersistenceContext
private EntityManager entityManager;
public void insert(User user) {
entityManager.persist(user);
}
public User load(int id) {
return entityManager.find(User.class, id);
}
}
J'ai le spring-config.xml suivant dans/src/main/resources:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-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.xsd">
<context:component-scan base-package="com.mydomain.orm" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:/persistence.xml" />
<property name="persistenceUnitName" value="userPersistenceUnit" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="HSQL" />
<property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect" />
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/mydb" />
<property name="username" value="my_user" />
<property name="password" value="" />
</bean>
</beans>
Et enfin et surtout, le fichier /src/main/resources/persistence.xml suivant:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://Java.Sun.com/xml/ns/persistence"
version="1.0">
<persistence-unit name="userPersistenceUnit" transaction-type="RESOURCE_LOCAL" >
<class>com.mydomain.orm.User</class>
</persistence-unit>
</persistence>
Que dois-je faire pour résoudre cette erreur?
Vous voulez un EntityManager
injecté, mais vous n'avez aucune annotation d'injection sur le terrain, et "factory" n'est pas le bon qualificatif dans tous les cas. Annotez votre champ avec @PersistenceContext
, En utilisant unitName
si nécessaire pour faire la distinction entre plusieurs unités de persistance.
Réponse à la question modifiée: Votre fichier XML n'est pas inclus, car vous commencez à partir de la classe Application
, et Spring suit simplement le @ComponentScan
À partir de là. Ajoutez cette importation à votre classe Application
(ou à toute classe @Configuration
Scannée):
@ImportResource("classpath:spring-config.xml")
Vous pouvez également migrer votre configuration XML vers le format JavaConfig, que Spring analysera en tant que composant.
Votre problème est que vous utilisez une configuration d'annotation qui recherche déjà le chemin de classe pour les beans annotés, cela tente d'instancier la UserDAO
mais vous ne fournissez pas d'entitéManagerFactory ici.
Vous pouvez combiner JavaConfig avec la configuration XML via @ImportResource("classpath:spring-config.xml")
.
@Configuration
@ComponentScan
@EnableAutoConfiguration
@ImportResource("classpath:spring-config.xml")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Controller
public class GetController {
@Autowired
UserService userService;
@RequestMapping(value = "/user", method = RequestMethod.GET)
public @ResponseBody User getUser(@RequestParam(value="id", required=true) int id) {
return userService.getUser(id);
}
}
@Component
public class UserService {
@Autowired
private UserDAO UserDao;
public User getUser(int id) {
return getUserDao().load(id);
}
}
Puis-je suggérer d'utiliser SpringData pour le DAO, vous économiserez beaucoup de code standard.
En regardant le rapport de configuration automatique qui est sorti du crash, je peux voir qu'il n'y a pas de DataSource
défini. Spring Boot en créera un pour vous si vous avez les bonnes choses sur votre chemin de classe - par exemple au minimum pour que quelque chose fonctionne, incluez h2 ou hsqldb sur votre chemin de classe.
Par ailleurs, le fichier XML est redondant si vous utilisez Spring Boot de la bonne façon.