2013-04-11 123 views
3

我遵循YouTube視頻教程來設置Spring JPA項目,但即時通訊仍然存在與我的Spring JPA項目有關的問題,並希望有人能夠提供幫助。Spring JPA倉庫Autowire問題

http://www.youtube.com/watch?v=kM7Gr3XTzIg

的主要問題似乎是自動裝配我JPARepository。我已經通過以下測試代碼測試了我的entityManager/persistence單元的工作原理(它將預期記錄拉回)。

public class CheckEntityManagerWorksTest { 
    private static Logger logger = Logger.getLogger(CheckEntityManagerWorksTest.class.getName()); 

    private static EntityManagerFactory emFactory; 

    private static EntityManager em; 

    @BeforeClass 
    public static void setUp() throws Exception { 
     try { 
      logger.info("Building JPA EntityManager for unit tests"); 
      emFactory = Persistence.createEntityManagerFactory("pu"); 
      em = emFactory.createEntityManager(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
      fail("Exception during JPA EntityManager instanciation."); 
     } 
    } 

    @AfterClass 
    public static void tearDown() throws Exception { 
     logger.info("Shuting down Hibernate JPA layer."); 
     if (em != null) { 
      em.close(); 
     } 
     if (emFactory != null) { 
      emFactory.close(); 
     } 
    } 

    @Test 
    public void testPersistence() { 
     try { 

      em.getTransaction().begin(); 

      Integer id = 51; 
      Accounts account = em.find(Accounts.class, id); 
      assertNotNull(account); 

      System.out.println("Account username: " + account.getUsername()); 

      em.getTransaction().commit(); 

     } catch (Exception ex) { 
      em.getTransaction().rollback(); 
      ex.printStackTrace(); 
      fail("Exception during testPersistence"); 
     } 
    } 
} 

正如我曾說過,測試適用於連接到數據庫等,但下面的測試失敗與自動裝配異常(堆棧跟蹤在頁面的最下方):

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration("**/applicationContext.xml") 
public class AccountsRepositoryTest { 

    @Autowired 
    AccountsRepository repo; 

    @Test 
    public void testAccountsRepository() { 
     assertNotNull(repo.findOne(51)); 
    } 
} 

下面是我的建立。

的persistence.xml

<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  http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" 
      version="2.0"> 
    <persistence-unit name="pu"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider> 
     <properties> 
      <property name="hibernate.connection.url" value="jdbc:derby://localhost:1527/craigtest"/> 
      <property name="hibernate.connection.password" value="craigtest"/> 
      <property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.ClientDriver"/> 
      <property name="hibernate.connection.username" value="craigtest"/> 
      <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" /> 
      <property name="hibernate.show_sql" value="true" /> 
     </properties> 
    </persistence-unit> 
</persistence> 

的applicationContext.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" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/data/jpa 
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> 

    <bean id="myEmf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"> 
     <property name="persistenceUnitName" value="pu"/> 
    </bean> 

    <bean id="myTxManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="myEmf"/> 
    </bean> 

    <jpa:repositories base-package="com.mycompany.jpaspring.repositories" /> 
</beans> 

我的倉庫:

package com.mycompany.jpaspring.repositories; 

import com.mycompany.jpaspring.entity.Accounts; 
import org.springframework.data.jpa.repository.JpaRepository; 

public interface AccountsRepository extends JpaRepository<Accounts, Integer>{ 

} 

我的實體:

package com.mycompany.jpaspring.entity; 

import java.io.Serializable; 
import javax.persistence.Basic; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.NamedQueries; 
import javax.persistence.NamedQuery; 
import javax.persistence.Table; 
import javax.xml.bind.annotation.XmlRootElement; 
@Entity 
@Table(name = "ACCOUNTS") 
@XmlRootElement 
@NamedQueries({ 
    @NamedQuery(name = "Accounts.findAll", query = "SELECT a FROM Accounts a"), 
    @NamedQuery(name = "Accounts.findById", query = "SELECT a FROM Accounts a WHERE a.id = :id"), 
    @NamedQuery(name = "Accounts.findByUsername", query = "SELECT a FROM Accounts a WHERE a.username = :username"), 
    @NamedQuery(name = "Accounts.findByFirstname", query = "SELECT a FROM Accounts a WHERE a.firstname = :firstname"), 
    @NamedQuery(name = "Accounts.findByLastname", query = "SELECT a FROM Accounts a WHERE a.lastname = :lastname")}) 
public class Accounts implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Basic(optional = false) 
    @Column(name = "ID") 
    private Integer id; 
    @Basic(optional = false) 
    @Column(name = "USERNAME") 
    private String username; 
    @Column(name = "FIRSTNAME") 
    private String firstname; 
    @Column(name = "LASTNAME") 
    private String lastname; 

    public Accounts() { 
    } 

    public Accounts(Integer id) { 
     this.id = id; 
    } 

    public Accounts(Integer id, String username) { 
     this.id = id; 
     this.username = username; 
    } 

    public Integer getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    public String getFirstname() { 
     return firstname; 
    } 

    public void setFirstname(String firstname) { 
     this.firstname = firstname; 
    } 

    public String getLastname() { 
     return lastname; 
    } 

    public void setLastname(String lastname) { 
     this.lastname = lastname; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 0; 
     hash += (id != null ? id.hashCode() : 0); 
     return hash; 
    } 

    @Override 
    public boolean equals(Object object) { 
     // TODO: Warning - this method won't work in the case the id fields are not set 
     if (!(object instanceof Accounts)) { 
      return false; 
     } 
     Accounts other = (Accounts) object; 
     if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) { 
      return false; 
     } 
     return true; 
    } 

    @Override 
    public String toString() { 
     return "com.mycompany.jpaspring.entity.Accounts[ id=" + id + " ]"; 
    } 

} 

堆棧跟蹤:

------------------------------------------------------------------------------- 
Test set: com.mycompany.jpaspring.AccountsRepositoryTest 
------------------------------------------------------------------------------- 
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.797 sec <<< FAILURE! 
testAccountsRepository(com.mycompany.jpaspring.AccountsRepositoryTest) Time elapsed: 0.507 sec <<< ERROR! 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.mycompany.jpaspring.AccountsRepositoryTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.mycompany.jpaspring.repositories.AccountsRepository com.mycompany.jpaspring.AccountsRepositoryTest.repo; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.mycompany.jpaspring.repositories.AccountsRepository] 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:287) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:374) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75) 
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:312) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) 
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:601) 
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164) 
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110) 
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175) 
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107) 
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68) 
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.mycompany.jpaspring.repositories.AccountsRepository com.mycompany.jpaspring.AccountsRepositoryTest.repo; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.mycompany.jpaspring.repositories.AccountsRepository] 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:513) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:92) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284) 
    ... 32 more 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.mycompany.jpaspring.repositories.AccountsRepository] 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:947) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:816) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:730) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:485) 
    ... 34 more 

回答

1

一切似乎沒什麼問題,除了這一行:

@ContextConfiguration("**/applicationContext.xml") 

你真的需要導入多個XML文件? 究竟哪個文件夾是applicationContext.xml? 你可以嘗試用完整的路徑引用替換上述內容嗎?事情是這樣的:

@ContextConfiguration("classpath:/com/.../application-context.xml") 
+0

感謝這個提示,這導致我失望的是幫我找到我的答案的路徑...我想有一個與正在進行一些瘋狂我的設置因@ContextConfiguration。當我將ContextConfiguration的路徑更改爲@ContextConfiguration(「classpath:/META-INF/applicationContext.xml」)時,突出顯示了stacktrace中的另一個錯誤:org.springframework.beans.factory.NoSuchBeanDefinitionException:沒有名爲'transactionManager'的bean是定義」。看來,當使用這種方法,你不能有一個像'myTxManager'這樣的名字...解決這個問題,然後解決我的Autowire問題 – Craig 2013-04-11 13:46:12