我有以下实体,并且每个实体都有一个对应的
CrudRepository
:
@Entity
class Movie {
@Id Long id;
@Column String name;
@ManyToOne Person director;
}
@Entity
class Person {
@Id Long id;
@Column String name;
}
我的控制器看起来像这样:
@RestController
@RequestMapping("/movies")
class MovieController {
private MovieRepository movies = ...;
private PersonRepository people = ...;
@PostMapping
public Movie create(@RequestBody MovieRequest request) {
// Get the director
Person director = people.findById(request.directorId);
// Create the new movie
Movie movie = new Movie();
movie.name = request.name;
movie.director = director;
// Save the new movie
return movies.save(movie);
}
}
class MovieRequest {
String name;
Long directorId
}
如您所见,create
方法首先通过其id加载导演,然后创建新电影,最后保存它。这将导致两次数据库查询:第一次检索导演,第二次保存电影。
在这种情况下,这不是一个大问题,但可能存在具有许多关联的实体,这意味着为了实现单个插入可能需要执行许多查询。
问题:我想在单个数据库操作中保存新电影。有没有办法避免最初的人员查询?有没有更好的处理这种情况的方法?
getOne
方法比在这种情况下使用findById
更好,因为它获取引用而不是整个实体,但它仍然会去数据库检查ID是否存在,并在不存在时抛出EntityNotFoundException
。我真的希望能够将其作为单个数据库操作完成,这似乎可能吗? - ESalaPersonRepository
扩展JpaRepository
并调用getOne(id)
进行了测试,但它仍然获取实体。这是记录的查询:select person0_.id as id1_1_0_, person0_.name as name2_1_0_ from person person0_ where person0_.id=?
。 - ESala