将spring persistence repository注入服务层

时间:2014-01-20 20:17:20

标签: java spring spring-data-jpa

我是Spring框架的新手,我正试图从我的朋友的简单应用程序开始,这将收集有关我们公司的闲话。

我无法将持久性存储库注入服务层的问题。

这是域中唯一的类(Gossip.java):

package ru.gossips.core.domain;

public class Gossip {
    private Long id;
    private String text;

    public Gossip() {
    }

    public Gossip(Long id, String text) {
        this.id = id;
        this.text = text;
    }

    ... getters and setters omitted
}

这是他在持久层(PGossip.java)中的兄弟类:

package ru.gossips.persistence.domain;

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

@Entity
public class PGossip {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String text;

    protected PGossip() {
    }

    public PGossip(String author, String text) {
        this.text = text;
    }

    ... getters and setters omitted

    @Override
    public String toString() {
        return String.format(
                "Persistence: Gossip[id=%d, text='%s']",
                id, text);
    }
}

我还有一个闲话的存储库:

package ru.gossips.persistence.repository;

import org.springframework.data.repository.CrudRepository;
import ru.gossips.persistence.domain.PGossip;

public interface GossipRepository extends CrudRepository<PGossip, Long> {
}

...和八卦服务:

package ru.gossips.core.services;

import ru.gossips.core.domain.Gossip;

import java.util.List;

public interface GossipService {
    List<Gossip> requestAllGossips();
}

它的实施:

package ru.gossips.core.services;

import org.springframework.beans.factory.annotation.Autowired;
import ru.gossips.core.domain.Gossip;
import ru.gossips.persistence.repository.GossipRepository;
import ru.gossips.persistence.domain.PGossip;

import java.util.ArrayList;
import java.util.List;

public class GossipServiceImpl implements GossipService {
    // PROBLEM HERE!!!!
    @Autowired                               
    private GossipRepository gossipRepository;

    @Override
    public List<Gossip> requestAllGossips() {

        // converting all persistence gossips to domain gossips
        final List<Gossip> gossipList = new ArrayList<Gossip>();
        for (PGossip pGossip : gossipRepository.findAll()) {
            gossipList.add(new Gossip(pGossip.getId(), pGossip.getText()));
        }

        return gossipList;
    }
}

在这里,我收到了IntelliJ IDEA的警告:必须在有效的spring bean中定义自动成员。

但是,我已根据Spring Data Jpda Reference v 1.4.3完成了所有需要完成的工作:

  1. 声明扩展Repository或其子接口之一的接口,并将其键入它将处理的域类 - done
  2. 在界面上声明查询方法 - 我只使用CrudRepository提供的方法
  3. 设置Spring以为这些接口创建代理实例 - 这是最困难的一步。由于我使用 Java配置而不是 xml配置,我创建了Persitence配置(见下文)
  4. 注入存储库实例并使用它 - 在这里我收到警告。
  5. 我的持久性配置:

    package ru.gossips.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
    import org.springframework.orm.jpa.JpaTransactionManager;
    import org.springframework.orm.jpa.JpaVendorAdapter;
    import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
    import org.springframework.orm.jpa.vendor.Database;
    import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
    import org.springframework.transaction.PlatformTransactionManager;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    import javax.persistence.EntityManagerFactory;
    import javax.sql.DataSource;
    
    import static org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType.H2;
    
    @Configuration
    @EnableJpaRepositories(basePackages = "ru.gossips.persistence.repository")
    @EnableTransactionManagement
    public class PersistenceConfig {
        @Bean
        public DataSource dataSource() {
            //todo: how to make non-embedded database?
            return new EmbeddedDatabaseBuilder().setType(H2).build();
        }
    
        @Bean
        public JpaVendorAdapter jpaVendorAdapter() {
            HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
            hibernateJpaVendorAdapter.setShowSql(false);
            hibernateJpaVendorAdapter.setGenerateDdl(true);
            hibernateJpaVendorAdapter.setDatabase(Database.H2);
            return hibernateJpaVendorAdapter;
        }
    
        @Bean
        public PlatformTransactionManager transactionManager() {
            return new JpaTransactionManager();
        }
    
        @Bean
        public EntityManagerFactory entityManagerFactory() {
            LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    
            factory.setJpaVendorAdapter(jpaVendorAdapter());
            factory.setDataSource(dataSource());
    
            factory.setPackagesToScan("ru.gossips.persistence.domain");
            factory.afterPropertiesSet();
    
            return factory.getObject();
        }
    }
    

    WebApplicationInitializer中提到的PersistenceConfig getRootConfigClasses()也有CoreConfigDomainConfigCoreConfig.java。 然而,在花了大约一个星期试图理解出了什么问题后,我无法摆脱强烈的感觉,我错过了我的配置/代码中的一些非常愚蠢的错误。

    可能出现什么问题?

    提前致谢!

    已添加package ru.gossips.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import ru.gossips.core.services.GossipService; import ru.gossips.core.services.GossipServiceImpl; @Configuration public class CoreConfig { @Bean public GossipService gossipService() { return new GossipServiceImpl(); } }

    SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gossipService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private ru.gossips.persistence.repository.GossipRepository ru.gossips.core.services.GossipServiceImpl.gossipRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gossipRepository': Initialization of bean failed; nested exception is java.lang.IllegalStateException: No persistence exception translators found in bean factory. Cannot perform exception translation.
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:381)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:293)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4937)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
        at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1558)
        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:606)
        at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
        at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:620)
        at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:567)
        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:606)
        at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
        at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1487)
        at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:97)
        at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1328)
        at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1420)
        at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:848)
        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:606)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
        at sun.rmi.transport.Transport$1.run(Transport.java:177)
        at sun.rmi.transport.Transport$1.run(Transport.java:174)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:556)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:811)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:670)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)
    Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private ru.gossips.persistence.repository.GossipRepository ru.gossips.core.services.GossipServiceImpl.gossipRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gossipRepository': Initialization of bean failed; nested exception is java.lang.IllegalStateException: No persistence exception translators found in bean factory. Cannot perform exception translation.
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
        ... 56 more
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gossipRepository': Initialization of bean failed; nested exception is java.lang.IllegalStateException: No persistence exception translators found in bean factory. Cannot perform exception translation.
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1014)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:957)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
        ... 58 more
    Caused by: java.lang.IllegalStateException: No persistence exception translators found in bean factory. Cannot perform exception translation.
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:142)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.setBeanFactory(PersistenceExceptionTranslationInterceptor.java:118)
        at org.springframework.data.repository.core.support.PersistenceExceptionTranslationRepositoryProxyPostProcessor.<init>(PersistenceExceptionTranslationRepositoryProxyPostProcessor.java:44)
        at org.springframework.data.repository.core.support.TransactionalRepositoryFactoryBeanSupport.setBeanFactory(TransactionalRepositoryFactoryBeanSupport.java:85)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1572)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1540)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
        ... 67 more
    

    添加了: 这是我在部署app时获得的实际堆栈跟踪:

    @Bean
    public HibernateExceptionTranslator hibernateExceptionTranslator(){
        return new HibernateExceptionTranslator();
    }
    

    解决方案:

    非常感谢@RC的解决方案。

    简短解决方案:将此bean添加到您的配置中:

    {{1}}

    解决方案解释:link

1 个答案:

答案 0 :(得分:0)

通过GossipRepository接口添加@Repository,因为它将在Spring框架中将其标记为存储库bean,并且将由spring容器处理。

还要在服务类和接口上添加@Component,例如在你的问题 GossipService和GossipServiceImpl向Spring容器注册类