没有 [javax.persistence.EntityManager] 类型的合格 bean

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22301426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 14:49:45  来源:igfitidea点击:

No qualifying bean of type [javax.persistence.EntityManager]

javaspringhibernatejpa

提问by Thom

I am attempting to build a brand new Spring Framework 4.0 project without all of the magical gradle stuff, but simply kicking it old school.

我试图在没有所有神奇的 gradle 东西的情况下构建一个全新的 Spring Framework 4.0 项目,而只是简单地把它踢成老派。

I am following the tutorial here: http://spring.io/guides/tutorials/data/and am having some success. I'm simply stuck at this point.

我正在关注这里的教程:http: //spring.io/guides/tutorials/data/并且取得了一些成功。我只是被困在这一点上。

/**
 * 
 */
package com.corrisoft.air.db.integration;

import javax.persistence.EntityManager;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

import com.corrisoft.air.db.JPAConfiguration;

import static com.corrisoft.air.db.fixture.JPAAssertions.assertTableExists;
import static com.corrisoft.air.db.fixture.JPAAssertions.assertTableHasColumn;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { JPAConfiguration.class })
@Transactional
@TransactionConfiguration(defaultRollback = true)
public class PersonMappingIntegrationTests {

    @Autowired
    EntityManager manager;

    @Test
    public void thatItemCustomMappingWorks() throws Exception {
        assertTableExists(manager, "PERSONS");

        assertTableHasColumn(manager, "PERSONS", "FIRST_NAME");
        assertTableHasColumn(manager, "PERSONS", "LAST_NAME");
    }
}

When I run this unit test, I get the following stack trace:

当我运行这个单元测试时,我得到以下堆栈跟踪:

SEVERE: Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@68c884e] to prepare test instance [com.corrisoft.air.db.integration.PersonMappingIntegrationTests@7448bc3d]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.corrisoft.air.db.integration.PersonMappingIntegrationTests': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: javax.persistence.EntityManager com.corrisoft.air.db.integration.PersonMappingIntegrationTests.manager; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManager] is defined: expected single matching bean but found 2: entityManager,org.springframework.orm.jpa.SharedEntityManagerCreator#0
    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.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:384)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:326)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:212)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access
/**
 * 
 */
package com.corrisoft.air.db;

import java.sql.SQLException;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.orm.hibernate4.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
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 com.corrisoft.air.db.repository.PersonsRepository;

/**
 * @author Corrisoft Android Development
 * 
 */
@Configuration
@EnableJpaRepositories(basePackages = "com.corrisoft.db.repository", includeFilters = @ComponentScan.Filter(value = { PersonsRepository.class }, type = FilterType.ASSIGNABLE_TYPE))
@EnableTransactionManagement
public class JPAConfiguration {

    @Bean
    public DataSource dataSource() throws SQLException {
        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
        return builder.setType(EmbeddedDatabaseType.H2).build();
    }

    @Bean
    public EntityManagerFactory entityManagerFactory() throws SQLException {

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("com.corrisoft.air.model");
        factory.setDataSource(dataSource());
        factory.afterPropertiesSet();

        return factory.getObject();
    }

    @Bean
    public EntityManager entityManager(EntityManagerFactory entityManagerFactory) {
        return entityManagerFactory.createEntityManager();
    }

    @Bean
    public PlatformTransactionManager transactionManager() throws SQLException {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory());
        return txManager;
    }

    @Bean
    public HibernateExceptionTranslator hibernateExceptionTranslator() {
        return new HibernateExceptionTranslator();
    }
}
0(ParentRunner.java:53) at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: javax.persistence.EntityManager com.corrisoft.air.db.integration.PersonMappingIntegrationTests.manager; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManager] is defined: expected single matching bean but found 2: entityManager,org.springframework.orm.jpa.SharedEntityManagerCreator#0 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) ... 26 more Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManager] is defined: expected single matching bean but found 2: entityManager,org.springframework.orm.jpa.SharedEntityManagerCreator#0 at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:967) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480) ... 28 more

Based on observations followed by research, it would appear that it's telling me that there are two EntityManager classes. The first one is from the hibernate JPA jar, but can't find the second one. It would appear to be telling me it's in Spring ORM, but there's no definition within that class.

根据观察和研究,它似乎告诉我有两个 EntityManager 类。第一个来自 hibernate JPA jar,但找不到第二个。它似乎告诉我它在 Spring ORM 中,但该类中没有定义。

Here is the JPAConfiguration class being used in the test:

这是测试中使用的 JPAConfiguration 类:

@PersistenceContext
EntityManager em;

采纳答案by chrylis -cautiouslyoptimistic-

The EntityManagerinterface belongs to JPA and is implemented by JPA providers (such as Eclipse), not Spring, and it has its own injection annotation: @PersistenceContext. EntityManagerobjects are transaction-scoped and should not be exposed as beans as you're doing. Instead, either use the JPA annotation to inject the EntityManager:

EntityManager接口属于JPA,由JPA提供者(如Eclipse)实现,而不是Spring,并且有自己的注入注解:@PersistenceContext. EntityManager对象是事务范围的,不应像您所做的那样作为 bean 公开。相反,要么使用 JPA 注释注入EntityManager

@Autowired
PersonRepository pr;

or, since it looks like you're trying to use Spring repositories, inject the repository instead:

或者,由于您似乎正在尝试使用 Spring 存储库,因此请改为注入存储库:

@Bean
@Qualifier(value = "entityManager")
public EntityManager entityManager(EntityManagerFactory entityManagerFactory) {
    return entityManagerFactory.createEntityManager();
}

回答by Rene Felgentr?ger

though this article is pretty old and has already bean answered, i encountered the same problem with the oficial turorial spring-data-jpa on spring-io website.

虽然这篇文章已经很老了,并且已经回答了 bean,但我在 spring-io 网站上的官方 turorial spring-data-jpa 遇到了同样的问题。

the current spring data jpa example/spring io guide detects at least 2 beans implementing the interface "EntityManager". You must help spring what implementation to wire to. I recommend to add a qualifier.

当前 spring 数据 jpa 示例/spring io 指南检测到至少 2 个实现接口“EntityManager”的 bean。您必须帮助启动要连接的实现。我建议添加一个限定符。

In class JPAConfiguration add:

在 JPAConfiguration 类中添加:

@Autowired
@Qualifier(value = "entityManager")
EntityManager manager;

In the test class add:

在测试类中添加:

##代码##

Hope it helps you.

希望对你有帮助。

I would not necessarily use the "PersistenceContext", as spring handles the creation of transaction manager, entitymanager, beans, datasource etc.. "PersisenceConetext" annotation is basically defined for container managed entityfactory of an application server/ejb compliant container

我不一定会使用“PersistenceContext”,因为 spring 处理事务管理器、实体管理器、bean、数据源等的创建。“PersisenceConetext”注释基本上是为应用服务器/ejb 兼容容器的容器管理实体工厂定义的