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

Spring Boot+Hibernate保存员工时JpaSystemException异常求助

Spring Boot整合Hibernate保存员工时出现反射访问字段异常

调用/save/employee接口保存员工信息时抛出如下异常:

org.springframework.orm.jpa.JpaSystemException: Error accessing field [private com.example.hibernatespringboot.entities.Address com.example.hibernatespringboot.entities.Employee.address] by reflection for persistent property [com.example.hibernatespringboot.entities.Employee#address] : com.example.hibernatespringboot.entities.Employee@7a329261; nested exception is org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private com.example.hibernatespringboot.entities.Address com.example.hibernatespringboot.entities.Employee#address] by reflection for persistent property [com.example.hibernatespringboot.entities.Employee#address]


项目代码

启动类 HibernateSpringBootApplication.class

package com.example.hibernatespringboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;

@SpringBootApplication
@EnableAutoConfiguration
@EntityScan(basePackages= {"com.example.hibernatespringboot"})
public class HibernateSpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(HibernateSpringBootApplication.class, args);
    }

}

实体类

Employee 实体类

package com.example.hibernatespringboot.entities;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Table
@Entity
public class Employee {
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private Integer id;
    
    @Column(name="firstname")
    private String firstname;
    
    @Column(name="age")
    private Integer age;
    
    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="address_id")
    private Address address;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
    
    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public Employee() {
        
    }
    
    public Employee(String firstname, Integer age) {
        super();
        this.firstname = firstname;
        this.age = age;
    }
    
}

Address 实体类

package com.example.hibernatespringboot.entities;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table
public class Address {
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private Integer id;
    
    @Column(name="pincode")
    private String pincode;

    public Address() {
        
    }
    
    public Address(String pincode) {
        super();
        this.pincode = pincode;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getPincode() {
        return pincode;
    }

    public void setPincode(String pincode) {
        this.pincode = pincode;
    }
}

HibernateUtil 类

package com.example.hibernatespringboot.helper;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.example.hibernatespringboot.entities.Address;
import com.example.hibernatespringboot.entities.Employee;

public class HibernateUtil {
    private static SessionFactory sessionFactory; 
    
    static {
        sessionFactory = new Configuration()
                .configure("hibernate.cfg.xml")
                .addAnnotatedClass(Employee.class)
                .addAnnotatedClass(Address.class)
                .buildSessionFactory();
    }
    
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

EmployeeRepository 类

package com.example.hibernatespringboot.repositories;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.stereotype.Repository;

import com.example.hibernatespringboot.entities.Address;
import com.example.hibernatespringboot.entities.Employee;
import com.example.hibernatespringboot.helper.HibernateUtil;

@Repository
public class EmployeeRepository {
    public Integer saveEmployee() {
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
        Session session = null;
        Integer id  = null;
        try {
            Employee employee = new Employee("Mridul", 23);
            Address address = new Address("123456");
            employee.setAddress(address);
            session = sessionFactory.openSession();
            Transaction tx = session.beginTransaction();
            session.save(employee);
            tx.commit();
        }
        finally {
            if(session != null) session.close();
        }
        
        return id;
    }
}

EmployeeService 类

package com.example.hibernatespringboot.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.hibernatespringboot.repositories.EmployeeRepository;

@Service
public class EmployeeService {
    
    @Autowired
    EmployeeRepository employeeRepository;
    
    public Integer saveEmployee() {
        Integer id = null;
        id = employeeRepository.saveEmployee();
        return id;
    }
}

EmployeeController 类

package com.example.hibernatespringboot.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.hibernatespringboot.services.EmployeeService;

@RestController
public class EmployeeController {

    @Autowired
    EmployeeService employeeService;
    
    @PostMapping("/save/employee")
    public ResponseEntity<Integer> saveEmployee(){
        Integer id = employeeService.saveEmployee();
        HttpStatus status = id!=null?HttpStatus.CREATED:HttpStatus.NO_CONTENT;
        return new ResponseEntity<>(id, status);     
    }
}

hibernate.cfg.xml 配置文件

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <!-- JDBC Database connection settings -->
        <property name="connection.driver_class">org.postgresql.Driver</property>
        <property name="connection.url">jdbc:postgresql://localhost:5432/test-hibernate</property>
        <property name="connection.username">postgres</property>
        <property name="connection.password">root</property>

        <!-- JDBC connection pool settings ... using built-in test pool -->
        <property name="connection.pool_size">1</property>

        <!-- Select our SQL dialect -->
        <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>

        <!-- Echo the SQL to stdout -->
        <property name="show_sql">true</property>

        <property name="hibernate.hbm2ddl.auto">update</property>

    </session-factory>

</hibernate-configuration>

application.properties 配置文件

spring.datasource.url=jdbc:postgresql://localhost:5432/test-hibernate
spring.datasource.username=postgres
spring.datasource.password=root
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

问题原因及解决方案

核心原因

项目同时启用了Spring Boot自动配置的JPA上下文和自定义HibernateUtil创建的独立SessionFactory,导致实体类被两个不同的Hibernate实例加载,反射访问字段时出现类加载冲突。另外EmployeeRepository中未给返回的id赋值,导致接口始终返回null。

解决方案

方案一:移除自定义HibernateUtil,使用Spring JPA的EntityManager

  1. 删除HibernateUtil类
  2. 修改EmployeeRepository,通过@PersistenceContext注入EntityManager:
package com.example.hibernatespringboot.repositories;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;

import org.springframework.stereotype.Repository;

import com.example.hibernatespringboot.entities.Address;
import com.example.hibernatespringboot.entities.Employee;

@Repository
@Transactional
public class EmployeeRepository {
    
    @PersistenceContext
    private EntityManager entityManager;

    public Integer saveEmployee() {
        Employee employee = new Employee("Mridul", 23);
        Address address = new Address("123456");
        employee.setAddress(address);
        entityManager.persist(employee);
        return employee.getId();
    }
}

方案二:改用Spring Data JPA(更推荐)

  1. 创建EmployeeRepository接口继承CrudRepository:
package com.example.hibernatespringboot.repositories;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import com.example.hibernatespringboot.entities.Employee;

@Repository
public interface EmployeeRepository extends CrudRepository<Employee, Integer> {
}
  1. 修改EmployeeService:
package com.example.hibernatespringboot.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.hibernatespringboot.entities.Employee;
import com.example.hibernatespringboot.entities.Address;
import com.example.hibernatespringboot.repositories.EmployeeRepository;

@Service
public class EmployeeService {
    
    @Autowired
    EmployeeRepository employeeRepository;
    
    public Integer saveEmployee() {
        Employee employee = new Employee("Mridul", 23);
        Address address = new Address("123456");
        employee.setAddress(address);
        Employee savedEmployee = employeeRepository.save(employee);
        return savedEmployee.getId();
    }
}
  1. 删除HibernateUtil类,无需手动管理Session和事务,Spring会自动处理。

额外配置

在application.properties中添加JPA自动建表配置(按需选择):

spring.jpa.hibernate.ddl-auto=update

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 03:55:52