Spring Boot CRUD应用查询报错:No default constructor for entity
问题分析与修复方案
报错原因解析
首先看初始报错信息:
org.hibernate.InstantiationException: No default constructor for entity: : com.example.SpringAppliction.entity.Task at org.hibernate.tuple.PojoInstantiator.instantiate(PojoInstantiator.java:85) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final] ...
Hibernate要求实体类必须提供public修饰的无参构造函数,否则无法实例化数据库查询返回的实体对象。你后续虽然给Task实体添加了无参构造,但出现了新的问题:Postman返回的DTO数据全为空值。
核心问题定位
1. DTO构造函数空实现
你的TaskDTO中有一个带Student参数的构造函数,但它是空实现,没有给DTO的属性赋值:
public TaskDTO(Long taskid, String taskname, String description, Boolean complete, Student student) { // 无任何赋值逻辑 }
2. Service层构造函数调用不匹配
在TaskServiceIMPL中创建TaskDTO时,你传入的参数类型与TaskDTO的构造函数不匹配,最终调用了上述空实现的构造函数,导致所有属性都是默认值(null或0)。
修复步骤
步骤1:确保Task实体无参构造的访问权限
你的Task实体已经具备public无参构造,这部分无需修改:
public Task() { }
步骤2:修复TaskDTO构造函数
修改带Student参数的构造函数,补充属性赋值逻辑:
public TaskDTO(Long taskid, String taskname, String description, Boolean complete, Student student) { this.taskid = taskid; this.taskname = taskname; this.description = description; this.complete = complete; this.studentId = student.getStudentid(); // 需确保Student实体有获取ID的getter方法 }
步骤3:修正Service层的DTO创建逻辑
在TaskServiceIMPL中传入完整的参数,匹配修复后的构造函数:
@Override public List<TaskDTO> getAllTasks() { List<Task> getTasks = taskRepo.findAll(); List<TaskDTO> taskDTOList = new ArrayList<>(); for(Task t:getTasks) { TaskDTO taskDTO = new TaskDTO( t.getTaskid(), t.getTaskname(), t.getDescription(), t.getComplete(), t.getStudent() ); taskDTOList.add(taskDTO); } return taskDTOList; }
可选优化:用ModelMapper简化转换
如果不想手动编写转换逻辑,可以引入ModelMapper自动完成实体到DTO的映射:
- 添加Maven依赖:
<dependency> <groupId>org.modelmapper</groupId> <artifactId>modelmapper</artifactId> <version>3.1.1</version> </dependency>
- 配置ModelMapper Bean:
@Configuration public class AppConfig { @Bean public ModelMapper modelMapper() { return new ModelMapper(); } }
- 简化Service层代码:
@Autowired private ModelMapper modelMapper; @Override public List<TaskDTO> getAllTasks() { List<Task> getTasks = taskRepo.findAll(); return getTasks.stream() .map(task -> modelMapper.map(task, TaskDTO.class)) .collect(Collectors.toList()); }
内容的提问来源于stack exchange,提问作者John Peter
相关产品推荐
相关产品推荐

