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

Spring Boot CRUD应用运行时出现序列化异常求助

Spring Boot CRUD应用序列化异常排查

异常信息

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.project.TodoApp.entity.Employee$HibernateProxy$1NCHjs6v["hibernateLazyInitializer"]) 
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.15.3.jar:2.15.3] 
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1308) ~[jackson-databind-2.15.3.jar:2.15.3] 
at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:414) ~[jackson-databind-2.15.3.jar:2.15.3] 
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:53) ~[jackson-databind-2.15.3.jar:2.15.3] 
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:30) ~[jackson-databind-2.15.3.jar:2.15.3]

相关代码

EmployeeController

@PutMapping(path = "\"/update\"")
public Employee updateEmployee(@RequestBody EmployeeUpdateDTO employeeUpdateDTO)
{
    return employeeService.updateEmployees(employeeUpdateDTO);
}

EmployeeService

public interface EmployeeService {
    Employee updateEmployees(EmployeeUpdateDTO employeeUpdateDTO);
}

EmployeeServiceIMPL

public Employee updateEmployees(EmployeeUpdateDTO employeeUpdateDTO) {
    if(employeeRepo.existsById(employeeUpdateDTO.getEmployeeid()))
    {
        Employee employee = employeeRepo.getById(employeeUpdateDTO.getEmployeeid());
        employee.setEmployeename(employeeUpdateDTO.getEmployeename());
        employee.setAddress(employeeUpdateDTO.getAddress());
        employee.setMobile(employeeUpdateDTO.getMobile());
        employee.setActivestate(employeeUpdateDTO.isActivestate());

        employeeRepo.save(employee);
        return employee;
    }
    else
    {
        System.out.println("\"Employee ID Not Found\"");
    }
    return null;
}

EmployeeUpdateDTO

@AllArgsConstructor
@NoArgsConstructor
@Data
public class EmployeeUpdateDTO {
    private Long employeeid;
    private String employeename;
    private String address;
    private int mobile;
    private boolean activestate;
}

pom.xml依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.22</version>
    <scope>provided</scope>
</dependency>

问题原因

异常核心是Jackson无法序列化Hibernate生成的懒加载代理对象。employeeRepo.getById()返回的不是实际的Employee实体,而是Hibernate通过ByteBuddy生成的代理类,这个代理包含hibernateLazyInitializer属性,Jackson默认不知道如何序列化该属性,从而抛出异常。

解决方案

方案1:替换getById为findById

getById()是懒加载方法,返回代理对象;findById()会立即查询数据库返回实际实体(包装在Optional中)。修改Service实现:

public Employee updateEmployees(EmployeeUpdateDTO employeeUpdateDTO) {
    return employeeRepo.findById(employeeUpdateDTO.getEmployeeid())
            .map(employee -> {
                employee.setEmployeename(employeeUpdateDTO.getEmployeename());
                employee.setAddress(employeeUpdateDTO.getAddress());
                employee.setMobile(employeeUpdateDTO.getMobile());
                employee.setActivestate(employeeUpdateDTO.isActivestate());
                return employeeRepo.save(employee);
            })
            .orElseGet(() -> {
                System.out.println("Employee ID Not Found");
                return null;
            });
}

方案2:在实体类添加Jackson忽略注解

在Employee实体类上添加@JsonIgnoreProperties,忽略Hibernate懒加载相关属性:

@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Employee {
    // 实体字段和方法
}

方案3:禁用Jackson的FAIL_ON_EMPTY_BEANS特性(不推荐)

在Spring Boot配置类中添加配置,禁止空对象序列化失败,但这会隐藏其他潜在的序列化问题:

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        return objectMapper;
    }
}

方案4:使用OpenEntityManagerInViewFilter(谨慎使用)

启用该过滤器可以延长EntityManager生命周期到视图渲染阶段,避免懒加载问题,但可能导致性能问题和N+1查询:
在application.properties中添加:

spring.jpa.open-in-view=true

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:27:37