Ho seguito il tutorial pubblicato here per ottenere un'applicazione di base che funzioni con Spring Data JPA. Ora, come ho capito, utilizzando la configurazioneSpring Data JPA - iniezione fallita - BeanCreationException: Impossibile eseguire il campo autoporto
<jpa:repositories base-package="my.package.to.scan" />
dovrebbe tradursi in quel pacchetto beeing scansionato entro la primavera dati JPA per le interfacce estendono JpaRepository
e creare un fagiolo concreate di esso in modo che possa essere utilizzato ovunque nelle mie classi di servizio utilizzando semplici Primavera @Autowired
. Ma fallisce, dicendo che non può trovare un bean con className (che è il nome predefinito che il bean ottiene quando viene creato, semplicemente usando il ClassName decapitalizzato).
Tuttavia, quando configuro il fagiolo manualy nel mio applicationContext come questo:
<bean id="ClassName" class="my.package.to.scan.ClassName"/>
La primavera è in grado di trovare il fagiolo. Ovviamente ottengo un errore perché voglio creare un bean da un'interfaccia, che ovviamente non può funzionare. MA il punto è che sembra che la "creazione automatica dei bean" di Spring Data JPA sembra in qualche modo fallire.
Ho allegato il codice pertinente in modo da poterlo vedere. A proposito, dovrei menzionare che sto sviluppando un portlet, quindi non mi chiedo perché non ho una primavera-config. Attualmente sto usando un applicationConfig più un MyPortlet-Portlet.xml per le configurazioni del portlet (ma questo non dovrebbe essere rilevante per questo problema). Ho aggiunto le istruzioni di importazione solo per assicurarmi che non stia usando le lezioni/classi errate.
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 - solo un'interfaccia per la CustomerService
import model.entities.Customer;
public interface ICustomerService {
// example method
public Customer getCustomer(Long customerId);
}
CustomerService - la classe usata da mia logica dell'applicazione per ottenere/set di dati ORM
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 - il repository per la primavera dati 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);
}
cliente - la mia entità campione
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;
}
}
Sono appena tornato dall'inferno classpath con WebSphere (maledetto, che fu * * ed up prodotto) e ora sono qui. Spero che qualcuno possa aiutarmi con questo.
Una spiegazione di base di ciò che esattamente va storto e che forse fornisce una migliore comprensione della funzione di iniezione a molle auto sarebbe grande. Ho letto la documentazione di primavera, ma a dire il vero: ci sono tanti modi per configurare qualcosa e non è abbastanza visibile per me COSA è veramente necessario quando si sceglie uno degli stili di configurazione.
EDIT
Dopo aver cercato di aggiornare il progetto a cui sto ancora ricevendo l'errore.come richiesto qui un po 'più particolari (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 i cambiamenti che ho fatto Sulla base della discussione in corso) aggiunto come richiesto
<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" />
Il tuo CustomerRepository non ha bisogno dell'annotazione della risorsa. Inoltre, findById dovrebbe già essere fornito da JpaRepository. Suppongo che il tuo entityManager sia stato creato correttamente senza errori. Con dovrebbe essere sufficiente. Attiva il registro di debug per le classi Spring e controlla se c'è qualche errore lì. –
Luciano
Perché il CustomerService ha l'annotazione del repository anziché l'annotazione del servizio? – Luciano
controlla i miei commenti sulla risposta di Ryan Stewart. in sostanza perché ho seguito il tutorial che sembra essere incompleto. – masi