在非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:
- 创建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); } }
- 在
applicationContext.xml中配置该工具类:
<bean class="com.pending.util.SpringContextHolder" />
- 修改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

