为什么JPA会双插入子实体?

pio*_*oto 5 java jpa spring-data-jpa

我有一对实体,称它们为"Ticket"和"TicketComment".

门票有这个属性:

@OneToMany(mappedBy="ticket", cascade = CascadeType.ALL)
@OrderBy("date")
private List<TicketComment> comments = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)

而且,TicketComment有这个:

@ManyToOne
@JoinColumn(name="TKT_ID")
@NotNull
private Ticket ticket;
Run Code Online (Sandbox Code Playgroud)

我想,我正在使用的代码应添加一条新评论.但是,它似乎将新注释添加到数据库两次:

Ticket ticket = ticketRepo.findOne(id);

TicketComment newComment = new TicketComment();
// ...
newComment.setTicket(ticket);
ticket.getComments().add(newComment);

ticketRepo.save(ticket);
Run Code Online (Sandbox Code Playgroud)

我想在没有重复的子实体之前,我已经能够成功地与类似的实体做到这一点......我可能会缺少什么?


更新:解决方法似乎是:

  1. 为"TicketComment"创建另一个JpaRepository
  2. 将任何其他更新保存到Ticket,而不使用创建/添加注释ticketRepo.
  3. 创建新的注释,与ticket(newComment.setTicket(ticket);)链接,并用a保存ticketCommentRepo.

因此,有两个不同的保存,一个应该只影响父节点,另一个应该只影响子节点.

我想把它归结为一次保存,但我不确定是否可能?


更新2:澄清观察到的症状.

如果我尝试简单地保存我的父"Ticket"实体并添加新的"TicketComment",会发生什么情况,我看到在数据库中创建了两个不同的记录,具有不同的主键,但具有相同的注释文本,相同或接近所以,时间戳.

所以,例如,假设我发表了一个评论,如"看起来不错".即使我在调试器中确认在ticket.getComments()我再次加载票证的详细信息页面后,我的...中只显示了一个"看起来不错" ,我看到类似的内容:

me @ 2015-09-11 23:16:58:看起来不错

me @ 2015-09-11 23:16:59:看起来不错

当我查看正在准备的SQL语句的一些调试日志时,我看到为我的TicketComments表调用两个相同的INSERT语句,然后是我的Tickets表的单个UPDATE ...