org.springframework.beans.factory.NoSuchBeanDefinitionException:没有bean命名为' entityManagerFactory'可用

时间:2017-12-23 22:06:36

标签: spring hibernate spring-data-jpa

即使我在配置中有一个命名的entityManager,我也会收到此错误。

这是一个spring-boot应用程序,我正在以这种方式运行代码。

如下所示,我的配置名为entityManager,名为" mysqlEntityManager。

我做错了什么?为什么它一直试图使用" entityManager"而不是我的" mysqlEntityManager"?

申请失败

说明

com.example.demo.service.impl.BookServiceImpl中的Field bookDao需要一个名为' entityManagerFactory'的bean。无法找到。

动作:

考虑定义名为' entityManagerFactory'的bean。在你的配置中。

    /**
 * 
 */
package com.example.demo.configuration;

/**
 * @author denisputnam
 *
 */

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;

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

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.example.demo.entity.User;


/**
 * Spring configuration of the "mysql" database.
 * 
 * @author Radouane ROUFID.
 *
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "mysqlEntityManager", 
        transactionManagerRef = "mysqlTransactionManager", 
        basePackages = "com.example.demo.dao"
)
public class MysqlConfiguration {

    /**
     * MySQL datasource definition.
     * 
     * @return datasource.
     */
    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.mysql.datasource")
    public DataSource mysqlDataSource() {
        return DataSourceBuilder
                    .create()
                    .build();
    }

    /**
     * Entity manager definition. 
     *  
     * @param builder an EntityManagerFactoryBuilder.
     * @return LocalContainerEntityManagerFactoryBean.
     */
    @Bean(name = "mysqlEntityManager")
    @Primary
    public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder
                    .dataSource(mysqlDataSource())
                    .properties(hibernateProperties())
                    .packages("com.example.demo.enity")
                    .persistenceUnit("mysqlPU")
                    .build();
    }

    /**
     * @param entityManagerFactory
     * @return
     */
    @Bean(name = "mysqlTransactionManager")
    @Primary
    public PlatformTransactionManager mysqlTransactionManager(@Qualifier("mysqlEntityManager") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

    private Map<String, Object> hibernateProperties() {

        Resource resource = new ClassPathResource("hibernate.properties");
        try {
            Properties properties = PropertiesLoaderUtils.loadProperties(resource);
            properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
            return properties.entrySet().stream()
                                            .collect(Collectors.toMap(
                                                        e -> e.getKey().toString(),
                                                        e -> e.getValue())
                                                    );
        } catch (IOException e) {
            return new HashMap<String, Object>();
        }
    }
}

    /**
 * 
 */
package com.example.demo.dao;

import java.util.List;

import javax.transaction.Transactional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import com.example.demo.entity.Book;

/**
 * @author denisputnam
 *
 */

public interface BookDao extends JpaRepository<Book, Long> {
    @Query("SELECT b FROM Book b WHERE b.authorName = ?1")
    public List<Book> getByAuthor( String author );

    @Query("SELECT b FROM Book b WHERE b.title = ?1")
    public List<Book> getByTitle( String title );
}

服务实施:

    /**
 * 
 */
package com.example.demo.service.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo.dao.BookDao;
import com.example.demo.entity.Book;
import com.example.demo.service.BookService;

/**
 * @author denisputnam
 *
 */
@Service("bookService")
@Transactional(value="mysqlTransactionManager")
public class BookServiceImpl implements BookService {
    private final Logger log = Logger.getLogger (this.getClass());

    @PersistenceContext
    private EntityManager em;

    @Autowired
    private BookDao bookDao;

    /* (non-Javadoc)
     * @see com.example.demo.service.BookService#getByAuthorName(java.lang.String)
     */
    @Override
    public List<Book> getByAuthorName(String name) {
        return this.bookDao.getByAuthor(name);
    }

    /* (non-Javadoc)
     * @see com.example.demo.service.BookService#getByTitle(java.lang.String)
     */
    @Override
    public List<Book> getByTitle(String title) {
        return this.bookDao.getByTitle(title);
    }

    /* (non-Javadoc)
     * @see com.example.demo.service.BookService#create(java.lang.String, java.lang.String)
     */
    @Override
    public Book create(String title, String author) throws Exception {
        Book book = null;
        try {
            book = new Book();
            book.setAuthorName(author);
            book.setTitle(title);
            this.bookDao.saveAndFlush(book);
        }catch( Exception e ) {
            log.error("Error creating book: " + e.getMessage());
            throw new Exception(e);
        }

        return book;
    }

    /* (non-Javadoc)
     * @see com.example.demo.service.BookService#updateBook(java.lang.Long, java.lang.String, java.lang.String)
     */
    @Override
    public Book updateBook(Long id, String title, String author) throws Exception {
        Book book = null;
        try{
            book = bookDao.findOne(id);
            book.setAuthorName(author);
            book.setTitle(title);
            bookDao.saveAndFlush(book);
        }catch( Exception e ){
            log.error("Error updating the book: " + e.getMessage());
            throw new Exception(e);
        }
        return book;
    }

    /* (non-Javadoc)
     * @see com.example.demo.service.BookService#delete(java.lang.Long)
     */
    @Override
    public Book delete(Long id) throws Exception {
        Book book = null;
        try {
            book = bookDao.findOne(id);
            bookDao.delete(book);
        } catch (Exception e) {
            log.error("Error deleting the book: " + e.getMessage());
            throw new Exception(e);
        }
        return book;
    }

    /* (non-Javadoc)
     * @see com.example.demo.service.BookService#findAll()
     */
    @Override
    public List<Book> findAll() {
        return this.bookDao.findAll();
    }

    /* (non-Javadoc)
     * @see com.example.demo.service.BookService#findOne(java.lang.Long)
     */
    @Override
    public Book findOne(Long id) {
        return this.bookDao.findOne(id);
    }

}

pom.xml - 依赖项:

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-configuration-processor -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-autoconfigure -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
        </dependency>


         <dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-data-jpa</artifactId>
         </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>       

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

application.properties:

    #server.port=8090  do this in vm args as -Dserver.port=8090

spring.oracle.datasource.url=jdbc:oracle:thin:@localhost:1532/DEMODB

spring.oracle.datasource.username=denismp
spring.oracle.datasource.password=password
spring.oracle.datasource.driver-class-name=oracle.jdbs.driver.OracleDriver
#spring.oracle.datasource.jndi-name=java/comp/env/jdbd/demodb
#spring.oracle.jpa.properties.hibernate.hdm2dll=autoupdate
#spring.oracle.jpa.hibernate-connection.release_mode=on_close

spring.application.name=demo
#spring.jpa.properties.hibernate.current_session_context_class=org.springframwork.orm.hibernate4.SpringSessionContext

spring.basic.enable=false


# ------------------------------
# MYSQL DATABASE CONFIGURATION
# ------------------------------
spring.mysql.datasource.url=jdbc:mysql://localhost:3306/cars?autoReconnect=true&useSSL=false
spring.mysql.datasource.username=cars
spring.mysql.datasource.password=cars
spring.mysql.datasource.driver-class-name=com.mysql.jdbc.Driver

# -----------------------
# POSTGRESQL DATABASE CONFIGURATION
# -----------------------
spring.postgresql.datasource.url=jdbc:postgresql://localhost:5432/book_db
spring.postgresql.datasource.username=postgres
spring.postgresql.datasource.password=postgres
spring.postgresql.datasource.driver-class-name=org.postgresql.Driver

hibernate.properties:

    # Spring DATA JPA Configuration
hiberate.show_sql=true
hibernate.format_sql=true
hibernate.hbm2dll.auto=update
#hibernate.dialect=org.hibernate.dialect.Oracle11gDialect
#hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.createorupdate=update
hibernate.connection.release_mode=on_close
hibernate.id.new_genrator_mappings=true

更新了Application.java。我添加了@EnableAutoConfiguration。不知道这是否是必需的。:

    @EnableAutoConfiguration
@ComponentScan(basePackages = "com.example.demo")
@SpringBootApplication
@EntityScan("com.example.demo.entity")
@EnableJpaRepositories("com.example.demo.dao")
public class Application extends SpringBootServletInitializer implements WebApplicationInitializer{

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure( SpringApplicationBuilder application ) {
        return application.sources(applicationClass );
    }

    private static Class<Application> applicationClass = Application.class;
}

将这两行添加到application.properties文件中。这是生成表所必需的。这与以前版本的STS IDE不同:

    spring.jpa.generate-ddl=true
sprint.jpa.hibernate-ddl-auto=create

我修改了MysqlConfiguration.java文件,将具有&#34; mysqlTransactionManager和mysqlEntityManager的任何内容替换为transactionManager和entityManager。如果我想连接到多个数据库,这个问题关注我:

    package com.example.demo.configuration;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;

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

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

//import com.example.entity.User;

/**
 * Spring configuration of the "mysql" database.
 * 
 * @author Radouane ROUFID.
 *
 */
@Configuration
@EnableTransactionManagement
// @EnableJpaRepositories(
// entityManagerFactoryRef = "mysqlEntityManager",
// transactionManagerRef = "mysqlTransactionManager",
// basePackages = "com.example.demo.dao"
// )
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactory", 
        transactionManagerRef = "transactionManager", 
        basePackages = {
        "com.example.demo.dao" })
public class MysqlConfiguration {

    /**
     * MySQL datasource definition.
     * 
     * @return datasource.
     */
    @Primary
    @Bean
    @ConfigurationProperties(prefix = "spring.mysql.datasource")
    public DataSource mysqlDataSource() {
        return DataSourceBuilder.create().build();
    }

    /**
     * Entity manager definition.
     * 
     * @param builder
     *            an EntityManagerFactoryBuilder.
     * @return LocalContainerEntityManagerFactoryBean.
     */
    @Primary
    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(mysqlDataSource()).properties(hibernateProperties())
                .packages("com.example.demo.entity").persistenceUnit("mysqlPU").build();
    }

    /**
     * @param entityManagerFactory
     * @return
     */
    @Primary
    @Bean(name = "transactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

    private Map<String, Object> hibernateProperties() {

        Resource resource = new ClassPathResource("hibernate.properties");
        try {
            Properties properties = PropertiesLoaderUtils.loadProperties(resource);
            properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
            return properties.entrySet().stream()
                    .collect(Collectors.toMap(e -> e.getKey().toString(), e -> e.getValue()));
        } catch (IOException e) {
            return new HashMap<String, Object>();
        }
    }

    @Primary
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**");
            }
        };
    }

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

2 个答案:

答案 0 :(得分:0)

你可能错过了BookDao中的@Repository Annotation。如果没问题,请检查应用程序属性中的数据库名称,该属性应与您创建mysql / oracle数据库的数据库名称相匹配。

答案 1 :(得分:0)

我添加了对配置注释和application.properties文件所做的更改。我还将引用“mysqlTransactionManager”的服务中的任何内容更改为“transactionManager”。如果需要“transactionManager”和“enitityManager”来使事情发挥作用,也许有人可以解释如何连接到数据库以上。

现在我要发布这个作为答案。请纠正我做错的任何事情。

P.S。 (这里有点咆哮)我发现有人因为我没有对这个问题进行足够的研究而投票给我。这是一个非常大的假设,当然也没有帮助我解决我的问题,这就是我认为这个网站的用途。

仅供参考,在我发布问题之前,我已经将这个问题解决了3天,并进行了一整天的研究。如果解决方案如此明显,那么投票给我的人可能刚刚发布了答案,并且在这个问题上挣扎了几天。

无论如何,我希望这对某人有所帮助。如果有人有兴趣,我会把项目放在https://github.com/denismp/demo上。