Tôi đang khắc phục sự cố này trong một thời gian và không thể làm việc đó. Hy vọng một số bạn có thể dành thời gian của bạn để giúp tôi.Tự động lưu trữ dữ liệu mùa xuân không thành công
Kịch bản
Tôi đang tạo ứng dụng web sử dụng Spring MVC. Webapp này được cho là sử dụng một dự án Maven khác, có chứa lớp persistence. Lớp persistence hiện chỉ bao gồm một dịch vụ và kho dữ liệu Spring. Bản thân lớp kiên trì hoạt động dựa trên một cá thể MySQL cục bộ.
Vấn đề của tôi
Tôi có kiểm tra JUnit cho lớp kiên trì. Kiểm tra tải và lưu một thực thể. Điều này được xử lý trên dịch vụ. Cả hai hoạt động đều hoạt động tốt.
Bây giờ tôi đang thử cùng một phép thử JUnit trong dự án Maven của webapp. Một lần nữa tôi đang cố gắng để lưu và tải một thực thể. Nhưng lần này nó thất bại. Spring nói rằng tham chiếu Repository bên trong dịch vụ không thể được autowired, gây ra không có bean nào phù hợp.
Tôi đã thử nhiều cách để giải quyết vấn đề này. Ví dụ bằng cách sử dụng dây trực tiếp, cho vòng loại và một. Không có cách tiếp cận nào của tôi hoạt động. Tôi thậm chí còn xây dựng hai dự án Maven hoàn toàn mới, nơi tôi đã đơn giản hóa kịch bản, nhưng để lại các yếu tố cần thiết giống nhau. Ở đó nó hoạt động như một sự quyến rũ. Tôi không hiểu những gì tôi đang làm sai trên này, kể từ khi tôi thích nghi với các thiết lập từ ví dụ làm việc.
tập tin từ dự án kiên trì
persistence.xml
<?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:jpa="http://www.springframework.org/schema/data/jpa"
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/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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd" default-autowire="byName">
<tx:annotation-driven transaction-manager="transactionManager" />
<context:annotation-config />
<context:component-scan base-package="com.company.dev.webapp" />
<jpa:repositories base-package="com.company.dev.webapp.repository" query-lookup-strategy="create-if-not-found" />
<bean id="exceptionPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<!-- Data Source -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/webapp" />
<property name="username" value="root" />
<property name="password" value="" />
<property name="initialSize" value="20" />
</bean>
<!-- Hibernate -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="webapp-persistence" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="database" value="MYSQL" />
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
QuestionService
@NoRepositoryBean
public interface QuestionService extends QuestionRepository {
Question findById(Long id);
Question findByUniqueRef(String uniqueRef);
List<Question> findAll(Sort sort, Page page);
List<Question> findAll(Page page);
}
QuestionServiceImpl
@Transactional
@Service
public class QuestionServiceImpl implements QuestionService {
@Autowired
QuestionRepository questionRepository;
@Override
public Question save(Question entity) {
return questionRepository.save(entity);
}
[Some methods ommited]
}
QuestionRepository
@Transactional
@Repository
public interface QuestionRepository extends JpaRepository<Question, Long>{
}
tập tin từ dự án webapp
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- Spring Bind Macro -->
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>
<!-- Log4J -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.xml</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>15000</param-value> <!-- intervall in millisekunden!!! -->
</context-param>
<context-param>
<description>Zur Konfiguration von Log4j</description>
<param-name>webAppRootKey</param-name>
<!-- Diesen Wert bei jeder Anwendung anpassen! -->
<param-value>app.root</param-value>
</context-param>
<!-- Application Context -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:persistence-context.xml
/WEB-INF/spring/app-config.xml
</param-value>
</context-param>
<!-- Reads request input using UTF-8 encoding -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Enables clean URLs with JSP views e.g. /welcome instead of /app/welcome -->
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Log4j Konfiguration laden-->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- Handles all requests into the application -->
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/mvc-config.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>oemInViewFilter</filter-name>
<filter-class>
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
</filter-class>
<init-param>
<param-name>entityManagerFactoryBeanName</param-name>
<param-value>entityManagerFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>oemInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
app-config.xml
<?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
">
<!-- Application Message Bundle -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages/messages"/>
<property name="cacheSeconds" value="0"/>
</bean>
<!-- Services and Repositories -->
<bean class="com.company.dev.webapp.impl.SimpleQuestionRepository" id="questionRepository">
<!-- ... -->
</bean>
<!-- Events -->
<bean class="com.company.dev.webapp.event.impl.ApplicationContextEventGateway" id="eventGateway"/>
<!-- Search and indexing -->
<import resource="search-indexing.xml"/>
</beans>
MVC-config.xml
<?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
">
<!-- Application Message Bundle -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages/messages"/>
<property name="cacheSeconds" value="0"/>
</bean>
<!-- Services and Repositories -->
<bean class="com.company.dev.webapp.impl.SimpleQuestionRepository" id="questionRepository">
<!-- ... -->
</bean>
<!-- Events -->
<bean class="com.company.dev.webapp.event.impl.ApplicationContextEventGateway" id="eventGateway"/>
</beans>
thử JUnit
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration
@ContextConfiguration({"classpath:persistence-context.xml", "classpath:app-config.xml"})
@Transactional
public class QuestionServiceTest {
@Autowired
private QuestionService questServ;
private Question quest;
@Before
public void setUp() throws Exception {
if (quest == null) {
quest = new Question();
quest.setQuestion("Why?!");
quest.setText("Please help!");
quest.setCreationDate(new Date(System.currentTimeMillis()));
questServ.save(quest);
}
}
@Test
public void loadQuestion() {
Question check = questServ.findOne(quest.getId());
Assert.assertNotNull(check);
Assert.assertEquals(check, quest);
}
}
Các ngoại lệ
08:28:59 ERROR [test.context.TestContextManager]: Caught exception while allowing TestExecutionListener [org.springframewor[email protected]15a3a1] to prepare test instance [[email protected]]
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:333)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:220)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:301)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:303)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at junit.framework.JUnit4TestAdapter.run(JUnit4TestAdapter.java:39)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:518)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:1052)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:906)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'answerController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.company.dev.webapp.service.QuestionService com.company.dev.webapp.web.AnswerController.questionRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'questionServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.company.dev.webapp.repository.QuestionRepository com.company.dev.webapp.service.impl.QuestionServiceImpl.questionRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.company.dev.webapp.repository.QuestionRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1064)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:574)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:84)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:280)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:304)
... 24 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.company.dev.webapp.service.QuestionService com.company.dev.webapp.web.AnswerController.questionRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'questionServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.company.dev.webapp.repository.QuestionRepository com.company.dev.webapp.service.impl.QuestionServiceImpl.questionRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.company.dev.webapp.repository.QuestionRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:507)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:283)
... 38 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'questionServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.company.dev.webapp.repository.QuestionRepository com.company.dev.webapp.service.impl.QuestionServiceImpl.questionRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.company.dev.webapp.repository.QuestionRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1064)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:838)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:780)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:697)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
... 40 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.company.dev.webapp.repository.QuestionRepository com.company.dev.webapp.service.impl.QuestionServiceImpl.questionRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.company.dev.webapp.repository.QuestionRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:507)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:283)
... 51 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.company.dev.webapp.repository.QuestionRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:914)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:783)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:697)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
... 53 more
Đây là toàn bộ mã. Nếu cần gì khác, xin vui lòng cho tôi ngay bây giờ. Tôi đánh giá cao sự giúp đỡ về chủ đề này, vì tôi thực sự không biết cách giải quyết vấn đề này.
Trân trọng
Việc triển khai giao diện 'QuestionRepository' là gì? –
Không có triển khai 'QuestionRepository'. Thông qua sự kỳ diệu của dữ liệu mùa xuân, nó tự tạo ra một bean của kho lưu trữ cần thiết. Phải đủ để chú thích Giao diện bằng '@ Repository' và để cho gói của nó được quét với' 'Thiết lập trong' persistence- context.xml' –
Makenshi
Ok không biết điều đó :) Và tại sao 'QuestionService' kế thừa từ giao diện' QuestionRepository'. Vì nó được thực hiện bởi 'QuestionServiceImpl', bạn có thể gặp phải một loại phụ thuộc vòng tròn. –