使用Hibernate插入记录时触发NullPointerException:this.id为null
Hibernate插入记录时NullPointerException问题排查与解决
问题描述
首次向数据库插入Company记录时触发NullPointerException,错误信息:Cannot invoke "java.lang.Integer.intValue()" because "this.id" is null。表初始无数据,疑惑为何会出现id为空的情况。
相关代码与配置
1. Controller类
@Controller @RequestMapping("/company") public class CompanyController { @Autowired private CompanyManager companyManager; @PostMapping("/add") public String addCompany(Company company) { companyManager.saveCompany(company); return "redirect:/company/list"; } }
2. Company实体类(问题版本)
@Entity @Table(name = "company") public class Company { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } // 其他属性的getter/setter }
3. CompanyManager与DAO实现
// CompanyManagerImpl @Service public class CompanyManagerImpl implements CompanyManager { @Autowired private CompanyDAO companyDAO; @Override @Transactional public void saveCompany(Company company) { companyDAO.save(company); } } // CompanyDAOImpl @Repository public class CompanyDAOImpl implements CompanyDAO { @Autowired private SessionFactory sessionFactory; @Override public void save(Company company) { sessionFactory.getCurrentSession().save(company); } }
4. Spring与Hibernate核心配置
<context:component-scan base-package="com.example" /> <tx:annotation-driven transaction-manager="transactionManager" /> <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> <property name="annotatedClasses"> <list> <value>com.example.entity.Company</value> </list> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean>
5. 数据库表结构
CREATE TABLE company ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL );
完整异常堆栈
java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because "this.id" is null at com.example.entity.Company.getId(Company.java:15) at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:223) at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:5094) at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:4812) at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:294) at org.hibernate.event.internal.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:511) at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:80) at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:75) at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:635) at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:627) at org.hibernate.internal.SessionImpl.save(SessionImpl.java:672) at com.example.dao.CompanyDAOImpl.save(CompanyDAOImpl.java:18) at com.example.manager.CompanyManagerImpl.saveCompany(CompanyManagerImpl.java:21) at com.example.controller.CompanyController.addCompany(CompanyController.java:25) ...
问题原因与解决方案
核心原因
Hibernate执行save()时,会先判断实体是瞬时态(新建)还是持久态。由于Company实体的id字段未配置主键生成策略,Hibernate无法自动生成主键值,且在内部逻辑中尝试调用id.intValue()时触发空指针。
修复方案
修改Company实体类,为id字段添加@Id和@GeneratedValue注解,指定与数据库匹配的主键生成策略:
@Entity @Table(name = "company") public class Company { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 适配MySQL AUTO_INCREMENT private Integer id; private String name; // 原有getter/setter保持不变 public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } // 其他属性的getter/setter }
额外验证点
- 确认数据库表
id字段确实为自增类型(如MySQL的AUTO_INCREMENT) - 检查
@Transactional注解是否正确作用在业务方法上,确保Hibernate Session能正常获取事务上下文 - 验证表单参数是否正确绑定到
Company对象(非核心,但可排除其他潜在问题)
内容的提问来源于stack exchange,提问作者Tan
相关产品推荐
相关产品推荐

