我有一个电子游戏记录的实体:
public record VideoGame(
@Positive
Integer id,
@NotEmpty
String title,
@NotEmpty
String console,
@NotEmpty
String genre,
String publisher,
String developer,
Double critic_score,
Double other_sales,
LocalDate release_date,
LocalDate last_update
) { }
视频游戏存储库:
@Repository
public class VideoGameRepository {
private final JdbcClient jdbcClient;
public VideoGameRepository(JdbcClient jdbcClient) {
this.jdbcClient = jdbcClient;
}
public void create(VideoGame videoGame) {
var newVideoGame = jdbcClient.sql("INSERT INTO videogamesalestest (id, title, console, genre, publisher, developer, critic_score, release_date, last_update)" +
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
.param(List.of(videoGame.id(), videoGame.title(), videoGame.console(), videoGame.genre(), videoGame.publisher(), videoGame.developer(), videoGame.critic_score(), videoGame.release_date(), videoGame.last_update()))
.update();
Assert.state(newVideoGame == 1, "Failed to insert new videoGame");
}
}
以及一个控制器:
@RestController
@RequestMapping("/api/videogames")
public class VideoGameController {
private final VideoGameRepository videoGameRepository;
public VideoGameController(VideoGameRepository videoGameRepository) {
this.videoGameRepository = videoGameRepository;
}
@ResponseStatus(HttpStatus.CREATED)
@PostMapping("")
void create(@RequestBody VideoGame videoGame) {
videoGameRepository.create(videoGame);
}
}
我想允许客户端提交一个 POST 请求,该请求可能包含或不包含 VideoGame 记录的所有字段。
我尝试将 JSON 主体中的字段值设置为 null,然后发送请求:
{
"id": 1,
"title": "NewGame",
"console": "Xbox",
"genre": "Action",
"publisher": "CBGAMES",
"developer": "CBGAMES",
"critic_score": 10.0,
"total_sales": 9.9,
"na_sales": 5.0,
"jp_sales": 2.2,
"pal_sales": 0.5,
"other_sales": 0.1,
"release_date": "2025-01-07",
"last_update": null
}
但我收到状态 500 响应“内部服务器错误”。
我也尝试用@Nullable 注释记录中的字段,但是在存储库中收到一条警告,提示参数可能为空。
我该怎么做才能实现这一点?我需要创建一个类而不是记录来处理空值,还是有更“有弹性”的方法来实现。我也考虑过使用 Optional,但我读到这实际上并不是 Optional 想要实现的。我也不想限制客户端传递完整的记录,因为在我看来这没有意义。
解决办法:
记录实体默认不允许空值,因此在这种情况下直接使用记录类型不太合适。
可以使用常规 Java 类代替记录实体,以便手动处理空值。在类中,所有字段都可以是 Optional 类型,或者您可以保留它们作为其原始类型,但允许它们为空。