2015-08-07 3 views
0

Я пытаюсь использовать Spring Data JPA - использование CrudRepository без какой-либо реализации (все параметры по умолчанию).Spring Data JPA (CrudRepository) - BeanCreationException: Не удалось определить поле autowire

С моим кодом я имеющим это исключение:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springJpaContactService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.sample.hibernate.ContactRepository com.sample.hibernate.RepositoryContactServiceImpl.contactRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contactRepository': Invocation of init method failed; nested exception is java.lang.AbstractMethodError: org.springframework.data.repository.core.support.RepositoryFactorySupport.getTargetRepository(Lorg/springframework/data/repository/core/RepositoryInformation;)Ljava/lang/Object; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:834) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537) at com.sample.hibernate.HibernateJpaApplication.main(HibernateJpaApplication.java:15)

Есть мои классы, ответственные за CrudRepository:

ContactRepository:

package com.sample.hibernate; 

import java.util.List; 

import org.springframework.data.repository.CrudRepository; 

public interface ContactRepository extends CrudRepository<Contact, Long> { 

    List<Contact> findByFirstName(String firstName); 

    List<Contact> findByFirstNameAndLastName(String firstName, String lastName); 

} 

RepositoryContactService:

package com.sample.hibernate; 

import java.util.List; 

public interface RepositoryContactService { 
    List<Contact> findAll(); 

    List<Contact> findByFirstName(String firstName); 

    List<Contact> findByFirstNameAndLastName(String firstName, String lastName); 
} 

RepositoryContactServiceImpl:

Контакт:

package com.sample.hibernate; 

import java.io.Serializable; 
import java.util.Date; 
import java.util.HashSet; 
import java.util.Set; 

import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.EntityResult; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.JoinTable; 
import javax.persistence.ManyToMany; 
import javax.persistence.NamedQueries; 
import javax.persistence.NamedQuery; 
import javax.persistence.OneToMany; 
import javax.persistence.SqlResultSetMapping; 
import javax.persistence.Table; 
import javax.persistence.Temporal; 
import javax.persistence.TemporalType; 
import javax.persistence.Version; 

@Entity 
@Table(name = "contact") 
@NamedQueries({ 
     @NamedQuery(name="Contact.findAll", query="select c from Contact c"), 
     @NamedQuery(name = "Contact.findAllWithDetail", query = "select distinct c from Contact c left join fetch c.contactTelDetails t left join fetch c.hobbies h"), 
     @NamedQuery(name = "Contact.findById", query = "select distinct c from Contact c left join fetch c.contactTelDetails t left join fetch c.hobbies h where c.id = :id") }) 
@SqlResultSetMapping(name="contactResult", [email protected](entityClass=Contact.class) 
) 
public class Contact implements Serializable { 

    private static final long serialVersionUID = -8008307767408320097L; 
    private Long id; 
    private int version; 
    private String firstName; 
    private String lastName; 
    private Date birthDate; 
    private Set<ContactTelDetail> contactTelDetails = new HashSet<ContactTelDetail>(); 
    private Set<Hobby> hobbies = new HashSet<Hobby>(); 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "ID") 
    public Long getId() { 
     return id; 
    } 

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

    @Version 
    @Column(name = "VERSION") 
    public int getVersion() { 
     return version; 
    } 

    public void setVersion(int version) { 
     this.version = version; 
    } 

    @Column(name = "FIRST_NAME") 
    public String getFirstName() { 
     return firstName; 
    } 

    public void setFirstName(String firstName) { 
     this.firstName = firstName; 
    } 

    @Column(name = "LAST_NAME") 
    public String getLastName() { 
     return lastName; 
    } 

    public void setLastName(String lastName) { 
     this.lastName = lastName; 
    } 

    @Temporal(TemporalType.DATE) 
    @Column(name = "BIRTH_DATE") 
    public Date getBirthDate() { 
     return birthDate; 
    } 

    public void setBirthDate(Date birthDate) { 
     this.birthDate = birthDate; 
    } 

    @OneToMany(mappedBy = "contact", cascade = CascadeType.ALL, orphanRemoval = true) 
    public Set<ContactTelDetail> getContactTelDetails() { 
     return contactTelDetails; 
    } 

    public void setContactTelDetails(Set<ContactTelDetail> contactTelDetails) { 
     this.contactTelDetails = contactTelDetails; 
    } 

    public void addContactTelDetail(ContactTelDetail contactTelDetail) { 
     contactTelDetail.setContact(this); 
     getContactTelDetails().add(contactTelDetail); 
    } 

    public void removeContactTelDetail(ContactTelDetail contactTelDetail) { 
     getContactTelDetails().remove(contactTelDetail); 
    } 

    @ManyToMany 
    @JoinTable(name = "contact_hobby_detail", joinColumns = @JoinColumn(name = "CONTACT_ID"), inverseJoinColumns = @JoinColumn(name = "HOBBY_ID")) 
    public Set<Hobby> getHobbies() { 
     return hobbies; 
    } 

    public void setHobbies(Set<Hobby> hobbies) { 
     this.hobbies = hobbies; 
    } 

    @Override 
    public String toString() { 
     return "Contact [id=" + id + ", version=" + version + ", firstName=" 
       + firstName + ", lastName=" + lastName + ", birthDate=" 
       + birthDate + "]"; 
    } 

} 

приложение-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" 
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:jdbc="http://www.springframework.org/schema/jdbc" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation=" 
http://www.springframework.org/schema/jdbc 
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd 
http://www.springframework.org/schema/data/jpa 
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd 
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx.xsd 
http://www.springframework.org/schema/util 
http://www.springframework.org/schema/util/spring-util.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context.xsd"> 

    <jdbc:embedded-database id="dataSource" type="H2"> 
     <jdbc:script location="classpath:sql/schema.sql" /> 
     <jdbc:script location="classpath:sql/test-data.sql" /> 
    </jdbc:embedded-database> 

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

    <tx:annotation-driven transaction-manager="transactionManager" /> 

    <bean id="emf" 
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="jpaVendorAdapter"> 
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> 
     </property> 
     <property name="packagesToScan" value="com.sample.hibernate" /> 
     <property name="jpaProperties"> 
      <props> 
       <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop> 
       <prop key="hibernate.max_fetch_depth">3</prop> 
       <prop key="hibernate.jdbc.fetch_size">50</prop> 
       <prop key="hibernate.jdbc.batch_size">10</prop> 
       <prop key="hibernate.show_sql">false</prop> 
      </props> 
     </property> 
    </bean> 

    <context:component-scan base-package="com.sample.hibernate" /> 

    <jpa:repositories base-package="com.sample.hibernate" 
     entity-manager-factory-ref="emf" transaction-manager-ref="transactionManager" /> 
</beans> 

Я был бы рад любой подсказке. Этот пример из книги, и я проверил 3 раза уже с ним + онлайн-уроки, и я не знаю, почему он работает не так, как ожидалось ...

ответ

1

Все с аннотациями было в порядке - не нужно перемещать @Repository в ContactRepository. Это связано с тем, что ContactRepository расширяет CrudRepository, который сообщает Spring, что он может autowire со ссылкой в ​​RepositoryContactServiceImpl. Проблема была в конфигурации maven (поскольку вы правильно думали и благодарили за это).Я изменил:

<parent> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-parent</artifactId> 
    <version>1.3.0.M2</version> 
    <relativePath /> <!-- lookup parent from repository --> 
</parent> 

в

<parent> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-parent</artifactId> 
    <version>1.0.2.RELEASE</version> 
    <relativePath /> <!-- lookup parent from repository --> 
</parent> 

и теперь хранилище работает, как ожидалось.

0

У вас есть @Repository аннотация в неправильном месте. Ваш класс ContactRepository должен быть аннотирован @Repository.

Spring не смог авторизовать ваш ContactRepository, потому что он не управляется весной, так как вы его не аннотировали @Repository.

Кроме того, у вас есть @Transactional на вашем RepositoryContactServiceImpl, что сделает все открытые методы в этом классе транзакционных, так положить @Transactional на каждом из методов этого класса является излишним. Если вам нужно, чтобы каждый из методов имел разные транзакционные действия, вы можете оставить аннотацию @Transactional для каждого метода и изменить для каждого метода в соответствии с вашими потребностями. Затем вы можете удалить @Transactional из класса.

Однако, если каждый метод требует того же типа транзакции, как в приведенном примере, вы можете удалить @Transactional аннотации из каждого метода, и оставить @Transactional на уровне класса, и указать readOnly свойства там.

+0

Я полностью согласен с вами в отношении @Transactional stuff - Это было просто для тестирования пурпуры. – Gazeciarz

+0

Я добавил @Repository в ContactRepository, но он все равно не работает (это же исключение). Реализация ContactRepository не нужна, потому что она должна быть подана с CrudRepository, верно? Сегодня я провожу 3 часа борьбы с этим примером, и я не знаю, что не так. – Gazeciarz

+0

И вы удалили '@ Repository' из' RepositoryContactServiceImpl'? –

Смежные вопросы