REST API提交JSON后PostgreSQL数据库写入null值问题求助
问题:POST请求返回200状态码,但数据库color字段被写入null
我正在开发基于PostgreSQL数据库的REST API,通过Postman或Swagger发送JSON POST请求后,服务器返回200状态码,但数据库中color字段始终被写入null,而非请求JSON中的内容。
请求示例:
{ "color": "string" }
响应示例:
{ "id": 2, "color": null }
响应头:
connection: keep-alive content-type: application/json date: Thu06 Oct 2022 13:27:09 GMT keep-alive: timeout=60 transfer-encoding: chunked
以下是项目结构、配置文件及各层代码,用于排查问题根源:
项目结构
- controller
- dto
- model
- repository
- service
application.properties配置
spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.url=jdbc:postgresql://localhost/democalendareventapp spring.datasource.username=postgres spring.datasource.password=postgres spring.jpa.generate-dll=true spring.datasource.hikari.maximumPoolSize=2 spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL10Dialect #spring.jpa.hibernate.ddl-auto=update spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true spring.mvc.pathmatch.matching-strategy=ant_path_matcher
Model层:EventCategoryColor
package com.radocode.DemoCalendarEventApp.model; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.*; @Entity @NoArgsConstructor @Data @Table(name = "EventCategoryColor") public class EventCategoryColor { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String color; public EventCategoryColor(String color) { this.color = color; } }
Repository层:EventCategoryColorRepository
package com.radocode.DemoCalendarEventApp.repository; import com.radocode.DemoCalendarEventApp.model.EventCategoryColor; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; @Repository public interface EventCategoryColorRepository extends CrudRepository<EventCategoryColor, Long> { }
Service层接口:EventCategoryColorService
package com.radocode.DemoCalendarEventApp.service; import com.radocode.DemoCalendarEventApp.dto.requestDto.EventCategoryColorRequestDto; import com.radocode.DemoCalendarEventApp.model.EventCategoryColor; import org.springframework.stereotype.Service; import java.util.List; @Service public interface EventCategoryColorService { public EventCategoryColor addColor(EventCategoryColorRequestDto eventCategoryColorRequestDto); public List<EventCategoryColor> getColors(); public EventCategoryColor getColor(Long id); public EventCategoryColor deleteColor(Long id); public EventCategoryColor editColor(Long id, EventCategoryColorRequestDto eventCategoryColorRequestDto); }
Service层实现类:EventCategoryColorServiceImpl
package com.radocode.DemoCalendarEventApp.service; import com.radocode.DemoCalendarEventApp.dto.requestDto.EventCategoryColorRequestDto; import com.radocode.DemoCalendarEventApp.model.EventCategoryColor; import com.radocode.DemoCalendarEventApp.repository.EventCategoryColorRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.transaction.Transactional; import java.util.ArrayList; import java.util.List; @Service public class EventCategoryColorServiceImpl implements EventCategoryColorService { private final EventCategoryColorRepository eventCategoryColorRepository; @Autowired public EventCategoryColorServiceImpl(EventCategoryColorRepository eventCategoryColorRepository) { this.eventCategoryColorRepository = eventCategoryColorRepository; } @Override public EventCategoryColor addColor(EventCategoryColorRequestDto eventCategoryColorRequestDto) { EventCategoryColor eventCategoryColor = new EventCategoryColor(); eventCategoryColor.setColor(eventCategoryColor.getColor()); return eventCategoryColorRepository.save(eventCategoryColor); } @Override public List<EventCategoryColor> getColors() { List<EventCategoryColor> colors = new ArrayList<>(); eventCategoryColorRepository.findAll().forEach(colors::add); return colors; } @Override public EventCategoryColor getColor(Long id) { return eventCategoryColorRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("Color with Id: " + id + ", could not be found")); } @Override public EventCategoryColor deleteColor(Long id) { EventCategoryColor eventCategoryColor = getColor(id); eventCategoryColorRepository.delete(eventCategoryColor); return eventCategoryColor; } @Transactional @Override public EventCategoryColor editColor(Long id, EventCategoryColorRequestDto eventCategoryColorRequestDto) { EventCategoryColor colorToEdit = getColor(id); colorToEdit.setColor(eventCategoryColorRequestDto.getColor()); return colorToEdit; } }
DTO层:EventCategoryColorRequestDto
package com.radocode.DemoCalendarEventApp.dto.requestDto; import lombok.Data; @Data public class EventCategoryColorRequestDto { private String color; }
Controller层:EventCatogeryColorController
package com.radocode.DemoCalendarEventApp.controller; import com.radocode.DemoCalendarEventApp.dto.requestDto.EventCategoryColorRequestDto; import com.radocode.DemoCalendarEventApp.model.EventCategoryColor; import com.radocode.DemoCalendarEventApp.service.EventCategoryColorService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/event-category-color") public class EventCatogeryColorController { private final EventCategoryColorService eventCategoryColorService; @Autowired public EventCatogeryColorController(EventCategoryColorService eventCategoryColorService) { this.eventCategoryColorService = eventCategoryColorService; } @PostMapping("/add") public ResponseEntity<EventCategoryColor> addColor( @RequestBody final EventCategoryColorRequestDto eventCategoryColorRequestDto) { EventCategoryColor eventCategoryColor = eventCategoryColorService.addColor(eventCategoryColorRequestDto); return new ResponseEntity<>(eventCategoryColor, HttpStatus.OK); } @GetMapping("/get/{id}") public ResponseEntity<EventCategoryColor> getColorById(@PathVariable final Long id) { EventCategoryColor eventCategoryColor = eventCategoryColorService.getColor(id); return new ResponseEntity<>(eventCategoryColor, HttpStatus.OK); } @GetMapping("/get-all") public ResponseEntity<List<EventCategoryColor>> getColors() { List<EventCategoryColor> eventCategoryColors = eventCategoryColorService.getColors(); return new ResponseEntity<>(eventCategoryColors, HttpStatus.OK); } @DeleteMapping("/delete/{id}") public ResponseEntity<EventCategoryColor> deleteColor(@PathVariable final Long id) { EventCategoryColor eventCategoryColor = eventCategoryColorService.deleteColor(id); return new ResponseEntity<>(eventCategoryColor, HttpStatus.OK); } @PutMapping("/edit/{id}") public ResponseEntity<EventCategoryColor> editColor( @PathVariable final Long id, @RequestBody final EventCategoryColorRequestDto eventCategoryColorRequestDto) { EventCategoryColor eventCategoryColor = eventCategoryColorService.editColor(id, eventCategoryColorRequestDto); return new ResponseEntity<>(eventCategoryColor, HttpStatus.OK); } }
问题根源及修复方案
问题所在
在EventCategoryColorServiceImpl的addColor方法中,错误地将新创建的EventCategoryColor对象自身的color值(初始为null)赋值给自己:
eventCategoryColor.setColor(eventCategoryColor.getColor());
这段代码完全没有使用传入的eventCategoryColorRequestDto中的数据,导致存入数据库的color始终为null。
修复方法
修改addColor方法,从DTO中获取color值并设置到实体类中,有两种常用方式:
方式一:使用setter方法
@Override public EventCategoryColor addColor(EventCategoryColorRequestDto eventCategoryColorRequestDto) { EventCategoryColor eventCategoryColor = new EventCategoryColor(); // 从DTO中获取color值并设置到实体类 eventCategoryColor.setColor(eventCategoryColorRequestDto.getColor()); return eventCategoryColorRepository.save(eventCategoryColor); }
方式二:使用带参构造器
利用实体类已有的带参构造器,直接传入DTO中的color值:
@Override public EventCategoryColor addColor(EventCategoryColorRequestDto eventCategoryColorRequestDto) { EventCategoryColor eventCategoryColor = new EventCategoryColor(eventCategoryColorRequestDto.getColor()); return eventCategoryColorRepository.save(eventCategoryColor); }
额外优化建议
如果后续DTO和实体类的字段增多,可以使用Spring的BeanUtils.copyProperties工具类简化属性复制,避免手动编写大量setter代码:
import org.springframework.beans.BeanUtils; @Override public EventCategoryColor addColor(EventCategoryColorRequestDto eventCategoryColorRequestDto) { EventCategoryColor eventCategoryColor = new EventCategoryColor(); BeanUtils.copyProperties(eventCategoryColorRequestDto, eventCategoryColor); return eventCategoryColorRepository.save(eventCategoryColor); }
内容的提问来源于stack exchange,提问作者Dugas Radoslav
相关产品推荐
相关产品推荐

