Spring JPA プロジェクトをセットアップするための YouTube ビデオ チュートリアルに従いましたが、まだ Spring JPA プロジェクトに問題があり、誰かが助けてくれることを望んでいました。
http://www.youtube.com/watch?v=kM7Gr3XTzIg
主な問題は、JPARepository の自動配線にあるようです。次のテスト コードを使用して、entityManager / 永続化ユニットが機能することをテストしました (予想されるレコードをプルバックします)。
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