NoSuchBeanDefinitionException:没有找到依赖项的 JpaVendorAdapter 类型的合格 bean

NoSuchBeanDefinitionException: No qualifying bean of type JpaVendorAdapter found for dependency

我正在尝试在内存数据库中设置基于 Java 的 hibernate 并从测试开始使用它,但是当加载 Hibernate bean 时应用程序上下文失败。这个练习的重点是使用 CrudRepository 和 WRITE

来设置带有 CRUD 操作的简单服务

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.orm.jpa.JpaVendorAdapter] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1119) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ... 72 more

相关配置及源码:

hibernate.properties

jdbc.driverClassName = org.hsqldb.jdbcDriver
jdbc.url = jdbc:hsqldb:mem:press
jdbc.username = user
jdbc.password = 
hibernate.dialect=org.hibernate.dialect.HSQLDialect
hibernate.show_sql = false
hibernate.format_sql = false

HibernateConfig.java - 加载失败

@Configuration
@EnableTransactionManagement
@PropertySource(value = { "classpath:hibernate.properties" })
public class HibernateConfig {

    @Autowired
    private Environment environment;

    @Bean
    public EntityManagerFactory entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        lef.setDataSource(dataSource);
        lef.setJpaVendorAdapter(jpaVendorAdapter);
        lef.setPackagesToScan("net.agilob.press.entity");
        return lef.getNativeEntityManagerFactory();
    }

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan(new String[] { "net.agilob.press.entity" });
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
        dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
        dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
        dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
        return dataSource;
    }

    private Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
        properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
        properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
        properties.put("hibernate.hbm2ddl.auto", environment.getRequiredProperty("create-drop"));

        return properties;
    }

    @Bean
    @Autowired
    public HibernateTemplate getHibernateTemplate(SessionFactory sessionFactory) {
        HibernateTemplate hibernateTemplate = new HibernateTemplate(sessionFactory);
        return hibernateTemplate;
    }

    @Bean
    @Autowired
    public HibernateTransactionManager transactionManager(SessionFactory s) {
        HibernateTransactionManager txManager = new HibernateTransactionManager();
        txManager.setSessionFactory(s);
        return txManager;
    }
}

AppConfig.java - 作为测试配置加载的文件

@Configuration
@ComponentScan(basePackages = "net.agilob.press.entity")
@EnableJpaRepositories(basePackages = "net.agilob.press.entity.repository")
@Import(HibernateConfig.class)
public class AppConfig {

    @Bean
    public PostService getPostService() {
        return new PostService();
    }
}

PostServiceTest.java - 这个应该创建 Post 的实例,将其保存在内存数据库中并稍后提取(只是为了看看它是否有效):

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class, loader = AnnotationConfigContextLoader.class)
@Transactional
public class PostDAOTest {

    @Autowired
    private PostService postService;

    @Before
    public void setUp() {
        Post post = new Post();
        post.setContent("body");
        post.setDescription("description");
        post.setIntroduction("introduction");
        post.setTitle("title");
        post.setTitleBrowser("title browser");
        postRepository.save(post);
    }

    @Test
    public void testList() {
        // checks if spring wiring was correct
        assertNotNull("Problem with spring beans", postRepository);
        assertFalse(postRepository.findTop10ByTitleOrderByIdAsc().isEmpty());
    }
}

Post服务:

@Service("postService")
@Transactional
public class PostService {

    @Autowired
    private PostRepository postRepository;

...
}

Post存储库:

public interface PostRepository extends BaseRepository<Post, Long> {
}

我试图在 HibernateConfig 中再创建一个 @Beans 注释方法,该方法正在构建 JpaVendorAdapter 实例,但是当我 运行 测试失败时:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.persistence.EntityManager]: Factory method 'createSharedEntityManager' threw exception; nested exception is java.lang.NullPointerException at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ... 59 more Caused by: java.lang.NullPointerException at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.initProxyClassLoader(SharedEntityManagerCreator.java:199) at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.<init>(SharedEntityManagerCreator.java:191) at org.springframework.orm.jpa.SharedEntityManagerCreator.createSharedEntityManager(SharedEntityManagerCreator.java:163) at org.springframework.orm.jpa.SharedEntityManagerCreator.createSharedEntityManager(SharedEntityManagerCreator.java:120) at org.springframework.orm.jpa.SharedEntityManagerCreator.createSharedEntityManager(SharedEntityManagerCreator.java:92) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ... 60 more

我的pom.xml

所以我认为设置中还有其他问题。

非常感谢任何有关如何以更好的方式设计和设置它的帮助。

您确定您拥有所有必需的依赖项吗?

HibernateJpaVendorAdapter 在你的类路径上可用吗?

尝试添加依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>4.3.2.RELEASE</version>
</dependency>

为了让您的 entityManagerFactory 知道提供者 class 以及 jpa 方言,您需要在您的 entityManagerFactory bean 上设置 jpaVendorAdaptor。这可以作为

@Bean
public JpaVendorAdapter jpaVendorAdapter() {
    HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
    jpaVendorAdapter.setShowSql(true);
    jpaVendorAdapter.setDatabase(Database.HSQL);
    jpaVendorAdapter.setDatabasePlatform(MySQL5Dialect.class.getName());
    jpaVendorAdapter.setGenerateDdl(false);
    return jpaVendorAdapter;
}

并在您的 entityManagerFactory 中调用此方法,如下所示:

lef.setJpaVendorAdapter(jpaVendorAdapter());