首页 文章

Spring注释:@Component工作,@ Repository没有

提问于
浏览
2

我的 Spring 季应用程序没什么问题 . 这是我的代码:

(资料库)

import com.maciej.entities.Etwas;
import com.maciej.repository.EtwasRepository;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import java.util.List;

HERE IS THE PROBLEM -----  @Component works, while @Repository doesn't
public class EtwasHibernateRepository implements EtwasRepository {
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<Etwas> findAll() {
        return null;
    }

    @Override
    public Etwas create(Etwas etwas) {
        entityManager.persist(etwas);
        return etwas;
    }

    @Override
    public Etwas read(int id) {
        TypedQuery<Etwas> query = entityManager.createQuery("SELECT e FROM Etwas e WHERE e.id=:id", Etwas.class);
        query.setParameter("id", id);
        Etwas etwas = query.getSingleResult();
        return etwas;
    }

    @Override
    public Etwas update(Etwas etwas) {
        return null;
    }

    @Override
    public boolean delete(int id) {
        return false;
    }
}

这是我简单的服务类:

import com.maciej.entities.Etwas;
import com.maciej.repository.impl.EtwasHibernateRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class EtwasService {
    @Autowired
    private EtwasHibernateRepository etwasHibernateRepository;

    public boolean save(Etwas etwas){
        etwasHibernateRepository.create(etwas);
        return true;
    }

    public Etwas read(int id){
        return etwasHibernateRepository.read(id);
    }
}

和简单的测试类:

import com.maciej.Config;
import com.maciej.entities.Etwas;
import com.maciej.services.EtwasService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class Test {
    public static void main(String[] args){
        AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(Config.class);
        Etwas etwas = acac.getBean("etwas", Etwas.class);
        etwas.setSth("STATATASTAT");

        EtwasService etwasService = acac.getBean("etwasService", EtwasService.class);
        for(int i=0; i<=20; i++){
            etwasService.save(etwas);
        }

        System.out.println(etwasService.read(7).toString());

        System.out.println(etwas.getSth());
    }
}

问题是,当我用 @Component 注释 EtwasHibernateRepository 时,一切正常 . 当我添加,实际上是apoperly - @Repository 注释我得到一个堆栈跟踪:你有没有建议我做错了什么?

ps代码非常简单,卷入并且仅用于测试所以不关心那个:)

线程“main”中的异常org.springframework.beans.factory.BeanCreationException:创建名为'etwasService'的bean时出错:注入自动连接的依赖项失败;嵌套异常是org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private com.maciej.repository.impl.EtwasHibernateRepository com.maciej.services.EtwasService.etwasHibernateRepository;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖项找到类型为[com.maciej.repository.impl.EtwasHibernateRepository]的限定bean:期望至少有一个bean可以作为此依赖项的autowire候选者 . 依赖注释:{org.springframework.beans.factory.annotation.Autowired(required = true)}位于org.springframework.beans的org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292) . 在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)上的factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)位于org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:304)的org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)处的AbstractAutowireCapableBeanFactory.java:475) org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java :300)在org.springframework的org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703) . context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)位于org.springframework.context.antext.AnnotationConfigApplicationContext的org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) . (AnnotationConfigApplicationContext.java:84 )在sun.reflect的sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)的sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)的com.maciej.test.Test.main(Test.java:12)处 . DelegationMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)位于com.intellij.rt.execution.application.AppMain.main的java.lang.reflect.Method.invoke(Method.java:606)中(AppMain) .java:134)引起:org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private com.maciej.repository.impl.EtwasHibernateRepository com.maciej.services.EtwasService.etwasHibernateRepository;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖项找到类型为[com.maciej.repository.impl.EtwasHibernateRepository]的限定bean:期望至少有一个bean可以作为此依赖项的autowire候选者 . 依赖注释:{org.springframework.beans.factory.annotation.Autowired(required = true)}在org.springframework的org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508) . beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)... 17更多引起:org.springframework.beans .factory.NoSuchBeanDefinitionException:找不到[com.maciej.repository.impl.EtwasHibernateRepository]类型的限定bean用于依赖:预期至少有1个bean符合此依赖关系的autowire候选者 . 依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}位于org.springframework.beans的org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1103) . or.s.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)中的factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)... 19更多

Update: 配置

import com.maciej.entities.Etwas;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManagerFactory;
import java.util.Properties;

@Configuration
@ComponentScan
@EnableTransactionManagement
public class Config {
    @Bean
    public Etwas etwas(){
        return new Etwas();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setDataSource(dataSource());
        emf.setPackagesToScan(new String[]{"com.maciej.entities"});

        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        emf.setJpaVendorAdapter(vendorAdapter);
        emf.setJpaProperties(additionalProperties());
        return emf;
    }

    @Bean
    public BasicDataSource dataSource(){
        BasicDataSource bds = new BasicDataSource();
        bds.setUsername("root");
        bds.setPassword("maciek");
        bds.setUrl("jdbc:mysql://localhost:3306/test");
        bds.setDriverClassName("com.mysql.jdbc.Driver");
        return bds;
    }


    private Properties additionalProperties(){
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        properties.setProperty("hibernate.show_sql", "true");
        properties.setProperty("hibernate.format_sql", "true");
        return properties;
    }


    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf); //entityManagerFactory().getObject()
        return transactionManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
        return new PersistenceExceptionTranslationPostProcessor();
    }

}

1 回答

  • 2

    问题在于您没有编程到接口 .

    @Service
    @Transactional
    public class EtwasService {
    
        @Autowired
        private EtwasHibernateRepository etwasHibernateRepository;
    

    自动连接的依赖是完全实现的类,而它应该是 EtwasRepository . 这将使它适用于 @Component@Repository . 除此之外,它也是正确的方法 .

    @Service
    @Transactional
    public class EtwasService {
    
        @Autowired
        private EtwasRepository etwasHibernateRepository;
    

    使用 @Repository 注释的Bean将启用自动异常转换,这将应用于AOP . 默认情况下,Spring使用基于接口的JDK动态代理 . 它将创建一个实现 EtwasRepository 接口的动态类并应用aop拦截器 . 这使得 EtwasRepository 类型的bean不再是 EtwasHibernateRepository 类型的bean .

    注释bean @Component 时不应用此转换 .

    关于您的配置的注释不需要 PersistenceExceptionTranslationPostProcessor 的显式声明 . 这已经得到了解决 .

相关问题