Java 级联型';我不在@manytone工作
在使用Hibernate和MySQL的Spring Boot应用程序中,我有一个实体用于注释。注释可以有子注释。所以实体看起来像这样:Java 级联型';我不在@manytone工作,java,spring,hibernate,jpa,spring-data-jpa,Java,Spring,Hibernate,Jpa,Spring Data Jpa,在使用Hibernate和MySQL的Spring Boot应用程序中,我有一个实体用于注释。注释可以有子注释。所以实体看起来像这样: @Entity @Table(name = "comment") ... public class Comment extends AbstractAuditingModel { ... @ManyToOne @ManyToOne(cascade = {CascadeType.PERSIST, CascadeTyp
@Entity
@Table(name = "comment")
...
public class Comment extends AbstractAuditingModel {
...
@ManyToOne
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Comment parent;
@OneToMany(mappedBy = "parent", cascade = {CascadeType.MERGE, CascadeType.REMOVE}, fetch = FetchType.LAZY)
private List<Comment> children = new ArrayList<>();
}
@实体
@表(name=“comment”)
...
公共类注释扩展了AbstractAuditingModel{
...
@许多酮
@manytone(cascade={CascadeType.PERSIST,CascadeType.MERGE})
私人评论家长;
@OneToMany(mappedBy=“parent”,cascade={CascadeType.MERGE,CascadeType.REMOVE},fetch=FetchType.LAZY)
private List children=new ArrayList();
}
我认为,对于这样的配置,如果创建了一个具有集合父对象的新注释,hibernate应该更新父对象注释中的子对象列表。但是没有。所以我将尝试用一个代码示例来解释我的意思
Comment parent = new Comment();
parent = commentRepository.save(parent);
Comment child = new Comment();
child.setParent(parent);
commentRepository.save(child);
Comment parentFromDb = commentRepository.getOne(parent.getId());
List<Comment> children = parentFromDb.getChildren();
assert children != null && children.size() == 1;
注释父项=新注释();
父级=commentRepository.save(父级);
注释子项=新注释();
setParent(家长);
commentRepository.save(子级);
Comment parentFromDb=commentRepository.getOne(parent.getId());
List children=parentFromDb.getChildren();
断言孩子null&&children.size()==1;
所以我认为它应该可以工作,但唯一可行的方法是在获取孩子之前使用entityManager.refresh(parentFromDB)。在不注入entityManager的情况下,它是如何工作的
我不想将子对象添加到父对象的列表中,然后保存此父对象,因为抽象地说,父对象的列表可以包含很多子对象。我想这会对演出不利
通常,Hibernate在内存中保持持久状态。过程
将此状态同步到基础数据库的过程称为刷新
当我们使用save()方法时,与save()关联的数据
操作将不会刷新到数据库,除非
调用flush()或commit()方法
从
因此,您可以调用commentRepository.flush()代码>保存这2条注释后
Comment parent = new Comment();
parent = commentRepository.save(parent);
Comment child = new Comment();
child.setParent(parent);
commentRepository.save(child);
commentRepository.flush(); <---add the flush here
Comment parentFromDb = commentRepository.getOne(parent.getId());
List<Comment> children = parentFromDb.getChildren();
assert children != null && children.size() == 1;
注释父项=新注释();
父级=commentRepository.save(父级);
注释子项=新注释();
setParent(家长);
commentRepository.save(子级);
commentRepository.flush() 如果您的存储库是crudepository,请尝试以下方法
Comment parent = new Comment();
parent = commentRepository.save(parent);
Comment child = new Comment();
child.setParent(parent);
commentRepository.save(child);
commentRepository.flush();
Comment parentFromDb = commentRepository.findById(parent.getId()).get();
List<Comment> children = parentFromDb.getChildren();
assert children != null && children.size() == 1;
注释父项=新注释();
父级=commentRepository.save(父级);
注释子项=新注释();
setParent(家长);
commentRepository.save(子级);
commentRepository.flush();
Comment parentFromDb=commentRepository.findById(parent.getId()).get();
List children=parentFromDb.getChildren();
断言孩子null&&children.size()==1;
repository.getOne无法工作,因为它没有从数据库重新加载父级。不幸的是,它的工作方式与此不同。即使使用@Transactional子列表,它也为空。到目前为止,我只有一个“解决方案”:entityManager.refresh(父级)。但是我认为Hibernate应该能够在创建子项后同步父项,而无需执行其他操作。请尝试切换到fetch=FetchType.EAGER
,然后再次在此处运行提供的解决方案
Comment parent = new Comment();
parent = commentRepository.save(parent);
Comment child = new Comment();
child.setParent(parent);
commentRepository.save(child);
commentRepository.flush();
Comment parentFromDb = commentRepository.findById(parent.getId()).get();
List<Comment> children = parentFromDb.getChildren();
assert children != null && children.size() == 1;