You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在非Controller类Order中使用Hibernate Bean遇空指针异常求助

问题

我尝试在Order类中使用CompanyManager接口,代码如下:

public class Order extends OrderBase implements CompanySummary, CompanyItem, Serializable {
private CompanyManager compLocMgr;
    
    public void setCompanyManager(CompanyManager companyLocationManager) {
        this.compLocMgr = companyLocationManager;
    }  
    
    public String getCompanyDisplay() {

        String result = "";
        if (companyHandler != null) {
            result = companyHandler.getAttribute(CompanyHandler.COMPANY_LOCATION);
            SampleLocation captureList = compLocMgr.getCompany(Integer.parseInt(result));
            System.out.println(captureList);
        }
        return result;
    } 

}

但持续出现以下错误:

[INFO] [talledLocalContainer] ERROR - CompanyAdminController.renderErrorPage(88) | 500 Internal Server Error - COMPANY ADMIN - URL: /companyadmin/casesearch.html Error: Cannot invoke "com.pending.service.CompanyManager.getCompany(java.lang.Integer)" because "this.compLocMgr" is null
[INFO] [talledLocalContainer] [2023-08-01 13:34:37,410] ERROR com.pending.web.controller.CompanyAdminController 500 Internal Server Error - COMPANY ADMIN - URL: /companyadmin/casesearch.html Error: Cannot invoke "com.pending.service.CompanyManager.getCompany(java.lang.Integer)" because "this.compLocMgr" is null
[INFO] [talledLocalContainer] [2023-08-01 13:34:37,410] ERROR com.pending.web.controller.CompanyAdminController 500 Internal Server Error - COMPANY ADMIN - URL: /companyadmin/casesearch.html Error: Cannot invoke "com.pending.service.CompanyManager.getCompany(java.lang.Integer)" because "this.compLocMgr" is null

我已在applicationContext.xml中定义了对应的Bean:

<bean id="companyManager" parent="txProxyTemplateMYDB">
    <property name="target">
    <bean class="com.pending.service.impl.CompanyManagerImpl">
       <property name="companyDAO">
          <ref bean="companyDAO" />
        </property>
    </bean>
    </property>
</bean>

此前在Spring Controller类中使用该Bean时,只需在companyadmin-servlet.xml中配置并添加setter方法即可正常使用,示例如下:

<bean id="companyCreateNewLocationController"
class="com.pending.web.controller.CompanyCreateNewLocationController">
    <property name="companyManager">
        <ref bean="companyManager" />
    </property>
</bean>

这是我首次在非Controller类(Order类)中尝试使用该Bean,却遇到此问题,请问我遗漏了什么配置?

相关类代码

com.pending.model.Company类

public class Company{
     
        private Integer id;
        private String name;
        private String comment;
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getComment() {
            return comment;
        }
        public void setComment(String comment) {
            this.comment = comment;
        }
}

com.pending.service.CompanyManager接口

public interface CompanyManager {
    public void setCompanyDAO(CompanyDAO dao);
    public Company getCompany(Integer id);  
    public void saveCompany(Company company);
}

com.pending.service.impl.CompanyManagerImpl类

public class CompanyManagerImpl implements CompanyManager {
    private CompanyDAO dao;
 
    public void setCompanyDAO(CompanyDAO dao) {
        this.dao = dao;
    }
 
    public void saveCompany(Company company) {
        dao.saveCompany(company);
    }
 
    public Company getCompany(Integer id) {
        return dao.getCompany(id);
    }
}

com.pending.dao.CompanyDAO接口

public interface CompanyDAO {
    public Company getCompany(Integer id);
    public Company saveCompany(Company company);
}

com.pending.dao.hibernate.CompanyDAOHibernate类

public class CompanyDAOHibernate extends HibernateDaoSupport implements CompanyDAO {
 
    @Override
    public Company saveCompany(Company company) {
        getHibernateTemplate().saveOrUpdate(company);
 
        if (logger.isDebugEnabled()) {
            logger.debug("Company id is: " + company.getId());
        }
        return company;
    }
 
    @Override
    public Company getCompany(Integer id) {
        Company company = (Company) getHibernateTemplate().get(Company.class, id);
        if (company == null) {
            throw new ObjectRetrievalFailureException(Company.class, id);
        }
        return company;
    }
}

Company.hbm.xml配置

<?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
   <hibernate-mapping>
   <class name="com.pending.model.Company" table="company">
   <id name="id" column="id" unsaved-value="null">
   <generator class="native" />
   </id>
   <property name="name" />
   <property name="comment" />
   </class>
   </hibernate-mapping>     
解决方案

问题核心在于Order类并未被Spring容器管理,Spring只会对自己容器内的Bean进行依赖注入,所以即便你写了setCompanyManager方法,也没有机会被Spring调用注入实例。可通过以下方式解决:

方式一:将Order类声明为Spring Bean

如果Order类适合被Spring管理,在applicationContext.xml中为Order类配置Bean并注入companyManager:

<bean id="order" class="com.pending.model.Order">
    <property name="companyManager" ref="companyManager" />
</bean>

后续获取Order实例时,必须从Spring容器中获取(比如通过ApplicationContext.getBean("order")),不能直接用new Order()。

方式二:手动从Spring容器获取CompanyManager实例

如果Order类无法被Spring管理(比如是Hibernate从数据库加载的实体),可通过Spring上下文工具类手动获取Bean:

  1. 创建Spring上下文工具类:
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class SpringContextHolder implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext ctx) {
        applicationContext = ctx;
    }

    public static <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }

    public static Object getBean(String beanName) {
        return applicationContext.getBean(beanName);
    }
}
  1. 在applicationContext.xml中配置该工具类:
<bean class="com.pending.util.SpringContextHolder" />
  1. 修改Order类的getCompanyDisplay方法,手动获取实例:
public String getCompanyDisplay() {
    String result = "";
    if (companyHandler != null) {
        result = companyHandler.getAttribute(CompanyHandler.COMPANY_LOCATION);
        // 手动从Spring容器获取实例
        CompanyManager compLocMgr = SpringContextHolder.getBean(CompanyManager.class);
        Company captureList = compLocMgr.getCompany(Integer.parseInt(result));
        System.out.println(captureList);
    }
    return result;
}

注意:代码中的SampleLocation应为笔误,实际需改为Company。

方式三:创建Order实例时手动注入CompanyManager

如果Order是在Spring管理的Bean(如Controller、Service)中创建的,可在创建时直接调用setCompanyManager传入实例:

// 示例:在Controller中创建Order
@Autowired
private CompanyManager companyManager;

public void someMethod() {
    Order order = new Order();
    order.setCompanyManager(companyManager);
    // 后续使用order实例
}

内容的提问来源于stack exchange,提问作者Tan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 14:37:07