2012-05-10 47 views
17

i theo hướng dẫn được đăng here để tải ứng dụng cơ sở để làm việc với JPA dữ liệu Spring. Bây giờ, làm thế nào tôi hiểu, sử dụng cấu hìnhJPA dữ liệu mùa xuân - lỗi không thành công - Trường BeanCreationException: Không thể tự động điền

<jpa:repositories base-package="my.package.to.scan" /> 

nên kết quả trong gói beeing quét bởi Spring liệu JPA cho các giao diện mở rộng JpaRepository và tạo một bean concreate của nó để nó có thể được sử dụng bất cứ nơi nào trong các lớp dịch vụ của tôi sử dụng đơn giản Mùa xuân @Autowired. Nhưng nó không thành công, nói rằng nó không thể tìm thấy một bean với className (đó là tên mặc định của bean được tạo ra, chỉ cần sử dụng ClassName không được viết hoa).

Tuy nhiên, khi tôi cấu hình đậu manualy trong applicationContext của tôi như thế này:

<bean id="ClassName" class="my.package.to.scan.ClassName"/> 

mùa xuân có thể tìm thấy hạt cà phê. Tôi sau đó tất nhiên có được một lỗi vì tôi muốn tạo ra một bean từ một giao diện, mà rõ ràng là không thể làm việc. NHƯNG điểm là có vẻ như dữ liệu Spring JPA "tạo bean tự động" dường như thất bại bằng cách nào đó.

Tôi đã đính kèm mã có liên quan để bạn có thể xem nó. Btw, tôi nên đề cập đến rằng tôi đang phát triển một portlet, do đó, không tự hỏi tại sao tôi không có một mùa xuân-config. Tôi hiện đang sử dụng một applicationConfig chỉ với một MyPortlet-Portlet.xml cho các cấu hình portlet (nhưng điều đó không nên liên quan đến vấn đề này). Tôi đã thêm các câu lệnh nhập để đảm bảo rằng tôi không sử dụng các chú thích/lớp sai.

applicationContext.xml

<beans *** ALL MY XMLN's and XSI's *** /> 
<context:annotation-config /> 
<jpa:repositories base-package="model.repositories" /> 

// JPA specific configuration here: dataSource, persistenceUnitManager exceptionTranslator, entityManagerFactory, SessionFactory, transactionManager - should not be relevant for this problem, tell me if i'm wrong 

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 

ICustomerService - chỉ là một giao diện cho hậu mãi

import model.entities.Customer; 
public interface ICustomerService { 
     // example method 
    public Customer getCustomer(Long customerId); 
} 

hậu mãi - lớp được sử dụng bởi logic ứng dụng của tôi để có được/dữ liệu ORM thiết

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.data.domain.Page; 
import org.springframework.data.domain.Pageable; 
import org.springframework.stereotype.Repository; 
import org.springframework.transaction.annotation.Transactional; 
import model.entities.Customer; 
import model.repositories.CustomerRepository; 
import model.service.interfaces.ICustomerService; 
@Repository 
@Transactional(readOnly = true) 
public class CustomerService implements ICustomerService{ 
    @Autowired 
    private CustomerRepository repository; 

    // example method 
    @Override 
    public Customer getCustomer(Long customerId){ 
     return repository.findById(customerId); 
    } 

CustomerRepository - kho cho mùa xuân dữ liệu JPA

import javax.annotation.Resource; 
import org.springframework.data.jpa.repository.JpaRepository; 
import org.springframework.transaction.annotation.Transactional; 
import model.entities.Customer; 
@Resource 
@Transactional(readOnly = true) 
public interface CustomerRepository extends JpaRepository<Customer, Long>{ 

    public Customer findById(Long id); 
} 

khách hàng - đơn vị mẫu của tôi

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.Table; 

@Entity 
@Table(name = "Customers") 
public class Customer{ 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    @Column(name = "ID_CUSTOMER") 
    private Long id; 

    @Column(name = "dbfirstname") 
    private String firstName; 

    @Column(name = "dbname") 
    private String lastName; 

    public Long getId(){ 
     return id; 
    } 

    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; 
    } 
} 

tôi chỉ đến từ địa ngục classpath với WebSphere (chết tiệt, thật là một fu * * ed lên sản phẩm) và bây giờ tôi đang ở đây. hy vọng ai đó có thể giúp tôi với điều này.

Một lời giải thích cơ bản về những gì đã xảy ra sai và có thể cung cấp một sự hiểu biết tốt hơn về tính năng phun tự động của lò xo sẽ ​​là tuyệt vời. Tôi đã đọc tài liệu mùa xuân, nhưng để nói sự thật: có rất nhiều cách để cấu hình một cái gì đó và nó không phải là khá rõ ràng với tôi Điều gì là thực sự cần thiết khi lựa chọn một trong những phong cách cấu hình.

EDIT

Sau khi cố gắng cập nhật các dự án tôi vẫn đang nhận được lỗi.theo yêu cầu ở đây thêm một chút chi tiết (trace):

Exception created : org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customerService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private model.repositories.CustomerRepository model.service.CustomerService.repository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customerRepository': FactoryBean threw exception on object creation; nested exception is java.lang.NullPointerException 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106) 
    [...] 
     at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:522) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1563) 
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private model.repositories.CustomerRepository model.service.CustomerService.repository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customerRepository': FactoryBean threw exception on object creation; nested exception is java.lang.NullPointerException 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:506) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284) 
    ... 96 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customerRepository': FactoryBean threw exception on object creation; nested exception is java.lang.NullPointerException 
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:149) 
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:102) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1442) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:248) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:848) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:790) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478) 
    ... 98 more 
Caused by: java.lang.NullPointerException 
    at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus(JtaStatusHelper.java:73) 
    at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.isActive(JtaStatusHelper.java:115) 
    at org.hibernate.engine.transaction.internal.jta.CMTTransaction.join(CMTTransaction.java:149) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:1215) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.postInit(AbstractEntityManagerImpl.java:177) 
    at org.hibernate.ejb.EntityManagerImpl.<init>(EntityManagerImpl.java:89) 
    at org.hibernate.ejb.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:179) 
    at org.hibernate.ejb.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:174) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:600) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:376) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:517) 
    at $Proxy325.createEntityManager(Unknown Source) 

    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:234) 
    at $Proxy328.createNamedQuery(Unknown Source) 
    at org.springframework.data.jpa.repository.query.NamedQuery.<init>(NamedQuery.java:74) 
    at org.springframework.data.jpa.repository.query.NamedQuery.lookupFrom(NamedQuery.java:96) 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:128) 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:162) 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:71) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:303) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:157) 
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:120) 
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:39) 
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142) 

EDIT # 2 compleate applicationContext.xml (includeing những thay đổi tôi thực hiện dựa trên các cuộc thảo luận đang diễn ra) thêm theo yêu cầu

<context:annotation-config /> 

<jpa:repositories base-package="model.repositories" /> 

<context:component-scan base-package="model,model.repositories,model.service,controller" /> 

<bean class="model.service.CustomerService"/> 
<bean class="model.service.OrderService"/> 
<bean class="model.repositories.CustomerRepository"/> 
<bean class="model.repositories.OrderRepository"/> 


<bean id="myExceptionTranslator" class="org.springframework.orm.hibernate4.HibernateExceptionTranslator" /> 

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/mydata" 
    resource-ref="true" cache="true" /> 


<bean id="pum" 
    class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager"> 
    <property name="persistenceXmlLocations"> 
     <list> 
      <value>classpath*:META-INF/OverridePersistence.xml</value> 
     </list> 
    </property> 
    <property name="defaultDataSource" ref="dataSource" /> 
</bean> 


<bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="generateDdl" value="true" /> 
      <property name="database" value="MYSQL" /> 
     </bean> 
    </property> 
    <property name="persistenceUnitManager" ref="pum" /> 
    <property name="persistenceUnitName" value="default" /> 
</bean> 

<bean id="mySessionFactory" 
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="packagesToScan" value="model"/> 
    <property name="hibernateProperties"> 
     <value>hibernate.dialect=org.hibernate.dialect.MySQLDialect</value> 
    </property> 
</bean> 

<bean id="transactionManager" 
    class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory"/> 
    <property name="sessionFactory" ref="mySessionFactory" /> 
</bean> 

<tx:annotation-driven /> 

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 
+0

CustomerRepository của bạn không cần chú thích Tài nguyên. Ngoài ra, findById đã được JpaRepository cung cấp. Tôi giả định thực thể của bạnManager được tạo ra tốt mà không có lỗi. Với là đủ. Bật nhật ký gỡ lỗi cho các lớp Spring và kiểm tra xem có lỗi nào không. – Luciano

+0

Tại sao CustomerService của bạn có chú thích Kho lưu trữ thay vì chú thích Dịch vụ? – Luciano

+0

kiểm tra nhận xét của tôi về câu trả lời của Ryan Stewart. cơ bản bởi vì tôi đã làm theo hướng dẫn mà dường như không đầy đủ. – masi

Trả lời

19

Vấn đề là rất có thể trong một số cấu hình bạn đã không hiển thị. Nó cũng sẽ là tốt nếu bạn đăng lỗi bạn đang nhận được. Nó có thể khác với những gì bạn nghĩ.

Một điều tôi nhận thấy về cấu hình của bạn là bạn đang sử dụng context:annotation-config thay vì context:component-scan. Sau này sẽ tự động phát hiện và tạo hạt dựa trên họ chú thích @Component. Trước đây không làm điều đó.

Ngoài ra, mọi thứ bạn đăng có vẻ như nó sẽ hoạt động, mặc dù có một số điều kỳ lạ, mà tôi sẽ đến trong giây lát. Tôi đã sao chép tất cả mã đã đăng của bạn vào một dự án mẫu và điền vào một vài chi tiết, chẳng hạn như maven pom, một số persistence.xml và các phần còn thiếu của the applicationContext.xml. Tôi cũng đã thêm một phương thức "tạo" vào dịch vụ để nó thực sự sẽ làm điều gì đó. Với những người tại chỗ và một lớp học chính để lái xe tất cả, đó là một ví dụ runnable. Bạn có thể browse the code on github, hoặc bạn có thể sao chép và chạy nó với:

git clone git://github.com/zzantozz/testbed tmp 
cd tmp/stackoverflow/10539417-basic-spring-data-jpa 
mvn -q compile exec:java -Dexec.mainClass=rds.testbed.springDataJpa.SpringDataJp 

Bây giờ cho những điều kỳ lạ mà tôi nhận thấy. Từ trên cùng:

  • Với mã như được cung cấp, không cần PersistenceAnnotationBeanPostProcessor mà bạn đã thêm vào applicationContext.xml. Nó không làm gì cho bạn. Tất nhiên, cũng có thể có mã khác mà cần nó mà bạn đã không hiển thị.
  • Chú thích @Repository trên CustomerService của bạn là supposed to be used on DAO classes hoặc các lớp tương tác với cơ sở dữ liệu. Chú thích thích hợp cho một dịch vụ là @Service.
  • Chú thích @Resource trên ICustomerRepository của bạn chủ yếu là used for marking fields and methods for autowiring. Tôi không chắc chắn điều gì khiến bạn nghĩ rằng để đặt nó trên giao diện kho lưu trữ của bạn, nhưng nó không làm bất cứ điều gì ở đó.
  • Kho lưu trữ của bạn không được là @Transactional. Điều đó thuộc về dịch vụ của bạn, và bạn đã có nó ở đó, vì vậy đó là tốt. Lưu ý rằng nó vẫn hoạt động với @Transactional trên kho lưu trữ vì nó chỉ tham gia vào giao dịch hiện tại do dịch vụ bắt đầu.
  • Cần lưu ý một lần nữa rằng bạn không sử dụng component scanning, mặc dù bạn có chú thích @Component có liên quan (số @Repository trên dịch vụ của mình). Điều đó có thể gây ra cho bạn một số vấn đề. Thay vì bật quét thành phần, tôi đã tạo thủ công bean dịch vụ bằng cách sử dụng XML trong dự án mẫu.

Vì vậy ... nếu điều này không giải thích cho bạn, nếu bạn cho tôi một lỗi cụ thể, tôi có thể giải thích lý do bạn nhận được và cho bạn biết phải làm gì.

+0

tôi sẽ xem xét mã của bạn và xem qua. cho đến nay câu hỏi của bạn: - phải, có vẻ như tôi không cần PersistenceAnnotationBeanPostProcessor. Đối với gỡ lỗi tôi đã đi với "thử nhiều hơn và loại bỏ những gì bạn không cần sau khi nó hoạt động" - điều Repository là lạ tôi biết. nhưng hướng dẫn tôi đăng (câu đầu tiên trong câu hỏi của tôi) nói rằng nó đúng ngay từ khi lớp IS là kho lưu trữ ngay cả khi Dịch vụ được đặt tên - Tôi đã xóa chú thích Tài nguyên khỏi IFace - Chú giải xuyên quốc gia cũng được nêu trong hướng dẫn - Tôi không biết tôi đang sử dụng chức năng quét thành phần được insted của anno conf – masi

+0

Thẻ 'component-scan' [là một siêu của' chú thích-config'] (http://static.springsource.org/spring/ docs/3.0.x/spring-framework-reference/html/beans.html # beans-java-kết hợp-xml-centric-component-scan). Nó làm điều đó, cộng với nó quét các lớp được chú thích bởi bất kỳ chú thích '@ Component' liên quan nào. –

+0

Bài đăng trên blog mà bạn đang theo dõi cho rằng "dịch vụ" là một kho lưu trữ vì nó có một EntityManager được chèn vào nó, làm cho nó trở thành một "kho lưu trữ" truyền thống. Nó cũng đề cập đến ý định để giới thiệu một kho lưu trữ thực sự sau này, mặc dù nó không có vẻ để có được xung quanh với nó. CustomerService của bạn được tiêm một CustomerRepository, vì vậy rõ ràng một là một '@ Service' và một là' @ Repository'. –

Các vấn đề liên quan