spring - 当我运行测试用例时,实体管理器已成功注入(inject),但在运行 Web 应用程序时抛出 NullPointerException

标签 spring hibernate jersey entitymanager applicationcontext

我有一个奇怪的问题。我使用 applicatioContext bean 使用 PersistenceContext 注入(inject)实体管理器。但问题是,当我运行测试用例时,实体管理器已成功注入(inject),但在运行 Web 应用程序时会抛出 NullPointerException

这是我在其中注入(inject)entityManager的abstractRepository

package com.ajit.retail.repository;

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

public class AbstractRepository {

    @PersistenceContext(type = PersistenceContextType.EXTENDED)
    EntityManager entityManager;
}

这是我使用实体管理器的存储库

package com.ajit.retail.repository;

import com.ajit.retail.exception.InvalidIdException;
import com.ajit.retail.model.Buyer;
import org.springframework.stereotype.Repository;

import javax.persistence.NoResultException;

@Repository
public class BuyerRepo extends AbstractRepository {

    public Buyer getBuyer(String buyerName) throws InvalidIdException {
        javax.persistence.Query buyerId = entityManager.createNativeQuery("select b.buyer_id from buyer b where b.name = :name").setParameter("name", buyerName);
        Integer id;

        try {
            id = (Integer) buyerId.getSingleResult();

        } catch (NoResultException e) {
            return null;
        }

        return getBuyer(id);
    }

    public Buyer getBuyer(long buyerId) throws InvalidIdException {
        Buyer buyer = entityManager.find(Buyer.class, buyerId); **====> NULL**
        if (buyer == null) throw new InvalidIdException("Invalid Article ID");
        return buyer;
    }
}

这是我的 Controller ,它正在调用存储库方法

package com.ajit.retail.web;

import com.sun.jersey.spi.inject.Inject;
import com.ajit.retail.exception.InvalidIdException;
import com.ajit.retail.model.Buyer;
import com.ajit.retail.repository.*;
import org.springframework.stereotype.Component;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/buyer")
@Component
public class BuyerController {

    @Inject
    private BuyerRepo buyerRepo;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Buyer searchFields() throws InvalidIdException {
        String buyerId = "51";
        Buyer buyer;

        try {
            buyer = buyerRepo.getBuyer(Long.parseLong(buyerId));
        } catch (NumberFormatException e) {
            buyer = buyerRepo.getBuyer(buyerId);
        }

        return buyer;
    }
}

这些是正在通过的单元测试

包 com.ajit.retail.repository;

import com.ajit.retail.exception.InvalidIdException;
import org.hamcrest.core.IsEqual;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import static org.junit.Assert.assertThat;

public class BuyerRepoTest extends BaseRepository {

    @Autowired
    private BuyerRepo buyerRepo;

    @Test
    public void shouldGiveNameOfGivenBuyerId() throws InvalidIdException {
        assertThat(buyerRepo.getBuyer(2).getName(), IsEqual.equalTo("SupervisorDLS"));
    }

    @Test(expected = InvalidIdException.class)
    public void shouldThrowExceptionForInvalidBuyerId() throws InvalidIdException {
        buyerRepo.getBuyer(-10);
    }
}

这是基础存储库

 package com.ajit.retail.repository;

import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;

@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class BaseRepository extends AbstractTransactionalJUnit4SpringContextTests {

 }

这是applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/tx
  http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <context:annotation-config/>
    <context:component-scan base-package="com.ajit.retail"/>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.postgresql.Driver"/>
        <property name="url" value="jdbc:postgresql://localhost/retail"/>
        <property name="username" value="retail_user"/>
        <property name="password" value="password"/>
    </bean>

    <bean id="entityManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>

        <property name="packagesToScan" value="com.ajit.retail"/>

        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true"/>
                <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect"/>
            </bean>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManager"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>

    </beans>

请帮忙!

最佳答案

我通过替换解决了这个问题

 <servlet>
        <servlet-name>retail</servlet-name>

        **<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>**

        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>com.ajit.retail.web</param-value>
        </init-param>

        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>

         <load-on-startup>1</load-on-startup>
    </servlet>

<servlet>
        <servlet-name>retail</servlet-name>

        **<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>**

        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>com.ajit.retail.web</param-value>
        </init-param>

        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>

         <load-on-startup>1</load-on-startup>
    </servlet>

关于spring - 当我运行测试用例时,实体管理器已成功注入(inject),但在运行 Web 应用程序时抛出 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16625466/

相关文章:

java - 如果缺少@Produces 注释, Jersey 服务会返回什么?

Spring Boot 访问 H2 控制台

java - 从 Controller 下载安全页面,Spring security

java - EnversSchemaGenerator 无法解析为类型

hibernate - 如何将 Hibernate 从 4.3 升级到 5.2 以迁移到 JDK 10?

java - Swagger 不解析@XmlElementWrapper 注释

java - 测试 Jersey 应用程序,使用 Jersey Injection 内置框架注入(inject)类 (HK2)

java - 依赖倒置中的 'Inversion'是什么意思

spring - 从对象本身获取 AOP 代理

java - 如何映射 Map<String, int[]>?