2013-04-11 94 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