Spring Data Jpa OneToMany 同时保存子实体和父实体?



这是我的父实体。 注意:为简洁起见,删除了getter,setter,lombok注释。

@Entity
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@OneToMany(mappedBy = "board")
private Set<Story> stories = new HashSet<>();
}

下面是我的子实体

@Entity
public class Story {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "board_id")
@JsonIgnore
private Board board;
}

每个Board可以有多个Story,但每个Story都属于单个Board

现在在我的服务中的某个地方,我正在这样做:

public void addBoard(BoardDTO boardDto){
// create a new board object which is just a pojo
// by copying properties from boardDto
Board board = ...;
// create set of stories
List<String> defaultTitles = Arrays.asList("Todo", "In-Progress", "Testing", "Done");
Set<Story> stories = defaultTitles.stream().map(title -> Story.builder()
.title(title)
// assign a reference, I know this is wrong since board here is not
// saved yet or fetched from db, hence the question
.board(board) 
.build())
.collect(Collectors.toSet());
// This saves board perfectly, but in Story db, the foreign key column
// board_id is null, rightfully so since call to story table was not yet done.
Board save = boardRepository.save(Board.builder()
.title(board.getTitle())
.stories(stories)
.build());
}

我可以采取的一种方法是先保存板而不Set<Story>,然后将此保存的板设置为ref来保存故事。但这需要两个存储库调用和代码方面,它看起来不太好。

另外,我遇到麻烦的原因是因为在我运行此代码之前,我的数据库是空的。这是我们第一次进入的新记录。所以Board table还没有行。

那么,有没有办法一次性做到这一点呢?对于堆栈溢出的大多数其他问题,板实体已经从数据库获取,然后他们向其添加子实体并将其保存到数据库。但对我来说,数据库是全新的,我想同时添加一个新的父实体及其相应的子实体,至少在代码方面,即使休眠进行多个数据库调用也是如此。

是的,您只需要将更改从父级传递到子级:

@Entity
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@OneToMany(mappedBy = "board", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Set<Story> stories = new HashSet<>();
}

现在,每当您保存父表(Board(时,更改将级联到子表。还可以使用CascadeType.ALL而不是{CascadeType.PERSIST, CascadeType.MERGE}级联任何更改,例如删除(从父实体上的集合中删除子项时,将删除子表中的联接 ID(。

最新更新