Spring-boot+JPA EntityManager 注入失败

Spring-boot+JPA EntityManager inject fails

在我的 J2EE 应用程序中,我尝试使用 spring-boot 和 JPA 技术,将 EntityManager 注入 DAO 层。但是,我有一些问题...我的用户 CRUD 存储库:

@Repository
public class UserRepositoryImpl implements UserRepository {

@PersistenceContext(unitName = "data")
private EntityManager entityManager;
// and crud methods
}

我的 spring-启动应用程序 class:

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

}

最后是我的 persistence.xml,位于 src/main/resources/META-INF 文件夹中:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence          http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="data" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>com.example.domain.User</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="hibernate.connection.autocommit" value="false" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect" />
        <property name="hibernate.c3p0.min_size" value="4" />
        <property name="hibernate.c3p0.max_size" value="128" />
        <property name="javax.persistence.jdbc.url" value="jdbc:sqlserver://localhost:1433;databaseName=qwerty;sendStringParametersAsUnicode=false" />
        <property name="javax.persistence.jdbc.user" value="sa" />
        <property name="javax.persistence.jdbc.driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
        <property name="javax.persistence.jdbc.password" value="" />
        <property name="hibernate.hbm2ddl.auto" value="update" />
        <property name="hibernate.show_sql" value="false" />
    </properties>
</persistence-unit>

所以,当我尝试使用这个注入的 entityManager 时,我得到了 NullPointerException。其他@Autowired 字段注入没有任何问题。这段代码有什么问题?我需要一些额外的配置吗? 我是初学者(甚至不是初级开发人员),我确实对 Spring-boot 是什么以及如何配置它有一些误解,例如 xml 文件中的 Spring。如果由于注入 EM 而需要这样的 xml 配置,请说明如何进行。

upd2.依赖项

<dependencies>
    <!-- logger -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
    </dependency>

    <!-- db -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-c3p0</artifactId>
    </dependency>
    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
    </dependency>
    <dependency>
        <groupId>com.microsoft</groupId>
        <artifactId>sqljdbc4</artifactId>
    </dependency>
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.2.1</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.5.3</version>
    </dependency>

    <!-- csv -->
    <dependency>
        <groupId>com.opencsv</groupId>
        <artifactId>opencsv</artifactId>
        <version>3.3</version>
    </dependency>

    <!-- spring-boot -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>1.2.4.RELEASE</version>

        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>

    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j</artifactId>
        <version>1.2.4.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>4.1.6.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>1.2.4.RELEASE</version>

        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>

    </dependency>

您应该使用 spring-boot-starter-data-jpa

的依赖项
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

要使用持久性 xml,您应该按照文档中的说明定义一个 bean。

Spring doesn’t require the use of XML to configure the JPA provider, and Spring Boot assumes you want to take advantage of that feature. If you prefer to use persistence.xml then you need to define your own @Bean of type LocalEntityManagerFactoryBean (with id ‘entityManagerFactory’, and set the persistence unit name there.

http://docs.spring.io/spring-boot/docs/current/reference/html/howto-data-access.html#howto-use-traditional-persistence-xml

或者您可以完全跳过 persistence.xml 并在 application.properties 文件中定义连接属性。

引自文档

DataSource configuration is controlled by external configuration properties in spring.datasource.*. For example, you might declare the following section in application.properties:

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html#boot-features-connect-to-production-database

(更改驱动程序和其他数据以匹配您的环境)

祝你好运!

如果您想继续使用 persistence.xml 文件,只需在您的配置中添加以下代码 class

    @Bean
public LocalEntityManagerFactoryBean entityManagerFactory(){
    LocalEntityManagerFactoryBean factoryBean = new LocalEntityManagerFactoryBean();
    factoryBean.setPersistenceUnitName("data");
    return factoryBean;
}

您可以使用 java 配置来配置 jpa 持久性。下面的代码向您展示了配置示例:

@Component
public class JpaConfiguration {

    @Bean
    @Primary
    public DataSource dataSource() {

        final SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
        dataSource.setDriver(new org.postgresql.Driver());
        dataSource.setUrl("jdbc:postgresql://localhost:5432/users"); 
        dataSource.setUsername("postgres");
        dataSource.setPassword("admin");

        return dataSource;
    }

    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
        jpaVendorAdapter.setGenerateDdl(true);
        jpaVendorAdapter.setShowSql(true);
        jpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.PostgreSQLDialect");

        return jpaVendorAdapter;
    }  

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        lef.setPackagesToScan("tn.bergit.crud.entity");
        lef.setDataSource(dataSource());
        lef.setJpaVendorAdapter(jpaVendorAdapter());

        Properties properties = new Properties();
        properties.setProperty("hibernate.show_sql", "true");
        properties.setProperty("hibernate.jdbc.fetch_size", "100");
        properties.setProperty("hibernate.hbm2ddl.auto", "update");

        lef.setJpaProperties(properties);
        return lef;
    }    


}

你可以在github (click here)

上看到这个例子

如果您使用以下

,您从中请求 EntityManager 的 class 应该是一个 Spring Bean
public class Foo {
  @PersistenceContext
  private EntityManager entityManager;
}

在这里,如果您使用 new 关键字来获取上面 Foo class 的实例,那么 EntityManager 将为 null.

希望这对某人有所帮助!