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

Spring Boot保存Employee时出现非空属性引用空值错误排查

问题:Hibernate保存Employee时出现未定义字段的非空约束错误

我定义了如下Employee实体:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    private String firstname;
    private String lastname;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date dateOfBirth;

    private String city;
    private String address;
    private String phone;
    private String mobile;
    private String email;
    private String photo;
    private String username;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date hireDate;

    @OneToMany
    @JoinColumn(name = "teamsId", updatable = false, insertable = false)
    private List<Teams> teams;
    private Integer teamsId;
}

Repository层代码:

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Integer> {

}

Service层代码:

@Service
public class EmployeeService {
    @Autowired
    private EmployeeRepository employeeRepository;
    public Employee saveEmployeeAndReturnId(Employee employee){
        return employeeRepository.saveAndFlush(employee);
    }
}

Controller层代码片段:

@Autowired
private EmployeeService employeeService;
@PostMapping("/users/addNew")
public RedirectView addNew(Employee employee, RedirectAttributes redirectAttributes){
    System.out.println(employee.toString());

    Employee newEmployee = employeeService.saveEmployeeAndReturnId(employee);

    System.out.println(newEmployee.getId().toString());

执行后打印的Employee对象信息:

Employee(id=null, firstname=user, lastname=useruser, dateOfBirth=Tue Aug 24 00:00:00 CEST 1999, city=A, address=A, phone=A, mobile=add, email=user@gmail.com, photo=null, username=userr, hireDate=null, teams=null, teamsId=null)

同时出现如下错误:

2022-10-07 12:41:49.420 ERROR 11388 --- [nio-8081-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: not-null property references a null or transient value : com.mk.atmosfera.hr.models.Employee._employee_employeeIdBackref; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value : com.mk.atmosfera.hr.models.Employee._employee_employeeIdBackref] with root cause
org.hibernate.PropertyValueException: not-null property references a null or transient value : com.mk.atmosfera.hr.models.Employee._employee_employeeIdBackref

我并未在任何地方创建employee_id字段,但该字段却出现了,请问这个错误的原因是什么?我哪里出错了?


解答

错误原因

这个错误源于双向关联的非空约束冲突,_employee_employeeIdBackref是Hibernate自动生成的反向关联字段,对应Teams实体中指向Employee的@ManyToOne关联。

核心问题有两点:

  1. Teams实体中应该存在@ManyToOne(optional = false)的配置(强制要求每个Teams必须绑定一个Employee),但你当前保存的Employee对象中teams为null,导致Hibernate检测到反向关联的非空约束被违反。
  2. Employee中的@OneToMany配置逻辑混乱:
    • @JoinColumn(name = "teamsId")指定的是Teams表中指向Employee的外键字段,但你却在Employee实体中定义了teamsId字段——外键字段本应放在关联关系中"多"的一方(Teams),而非"一"的一方(Employee)。
    • insertable = false, updatable = false设置意味着该外键不由Employee维护,但结合Teams的非空关联要求,保存时Hibernate无法生成合法的关联数据,触发错误。

解决方法

方法1:修正双向关联配置(推荐)

  1. 删除Employee中的private Integer teamsId;字段,外键字段应放在Teams实体中。
  2. 修改Employee的@OneToMany配置,用mappedBy指定关联的维护方(即Teams中的关联字段):
    @OneToMany(mappedBy = "employee")
    private List<Teams> teams;
    
  3. 检查Teams实体的关联配置:
    • 如果不需要强制Teams必须关联Employee,去掉@ManyToOne的optional = false(默认optional = true,允许关联为空):
      @ManyToOne
      @JoinColumn(name = "employee_id") // Teams表中指向Employee.id的外键字段
      private Employee employee;
      
    • 如果确实需要强制关联,保存Employee时必须同时传入已持久化的Teams对象,或先保存Teams再建立关联。

方法2:改为单向关联

如果不需要双向关联,直接调整Employee的@OneToMany配置,明确指定Teams表中的外键:

@OneToMany
@JoinColumn(name = "employee_id") // Teams表中用于关联Employee的外键字段
private List<Teams> teams;

同时确保Teams实体中没有定义反向的@ManyToOne关联,或把反向关联的optional设为true。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 16:35:28