java - OneToMany 双向关系不显示孩子
问题描述
当我使用 parentId 创建 templateDir 时,它在 getAllTree 方法之后正确显示,如果我创建没有 parentId 的 templateFile 它也正确显示。 但是当我使用 parentDirId 创建 templateFile 时,它根本没有显示。它位于 db 中,但我假设的 parentDir 没有被正确识别为子项。
我有 2 个实体类:TemplateFile 和 TemplateDirectory:
模板文件
@Entity @Table(name = "template_files") public class TemplateFile implements TemplateEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private long id; @Column(name = "name", nullable = false) private String name; @Column(name = "local_path") private String localPath; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "directory_id", referencedColumnName = "id") private TemplateDirectory parentDir; @Column(name = "created_at", nullable = false) private Instant createdAt;
模板目录
@Entity @Table(name = "template_directories") public class TemplateDirectory implements TemplateEntity{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private long id; @Column(name = "name", nullable = false) private String name; @Column(name = "created_at", nullable = false) private Instant createdAt; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") private TemplateDirectory parent; @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true) private Set<TemplateDirectory> childDirs; @OneToMany(mappedBy = "parentDir", cascade = CascadeType.ALL, orphanRemoval = true) private Set<TemplateFile> childFiles;
当我使用 parentDirectory 创建新的 TemplateFile 时,我使用以下方法来确保双向关系(与创建新目录相同):
public void addChildTemplate(TemplateFile template) { template.setParentDir(this); this.childFiles.add(template); }
创建模板方法:
@Transactional public TemplateTreeDTO createTemplate(TemplateDTO templateDTO) throws NotFoundException { TemplateEntity templateEntity; if (templateDTO instanceof TemplateFileDTO) { TemplateFileDTO templateFileDTO = (TemplateFileDTO) templateDTO; if (templateFileDTO.getParentId() == null) { templateEntity = templateMapper.createEntityFromTemplateDTO(templateFileDTO, null); } else { TemplateDirectory parentDirectory = findTemplateDirectoryById(templateFileDTO.getParentId()); templateEntity = templateMapper.createEntityFromTemplateDTO(templateFileDTO, parentDirectory); } templateFileRepository.saveAndFlush((TemplateFile) templateEntity); } else { TemplateDirectoryDTO templateDirectoryDTO = (TemplateDirectoryDTO) templateDTO; if (templateDirectoryDTO.getParentId() == null) { templateEntity = templateMapper.createEntityFromTemplateDTO(templateDirectoryDTO, null); } else { TemplateDirectory parentDirectory = findTemplateDirectoryById(templateDirectoryDTO.getParentId()); templateEntity = templateMapper.createEntityFromTemplateDTO(templateDirectoryDTO, parentDirectory); } templateDirectoryRepository.saveAndFlush((TemplateDirectory) templateEntity); } return getAllTree();
}
模板映射器方法:
public TemplateEntity createEntityFromTemplateDTO(TemplateDTO templateDTO, TemplateDirectory parentDirectory) { if (templateDTO instanceof TemplateFileDTO) { TemplateFile templateFile = new TemplateFile(); updateEntityFromTemplateDTO(templateFile, templateDTO, parentDirectory); return templateFile; } else { TemplateDirectory templateDirectory = new TemplateDirectory(); updateEntityFromTemplateDTO(templateDirectory, templateDTO, parentDirectory); return templateDirectory; } } public TemplateEntity updateEntityFromTemplateDTO(TemplateEntity templateEntity, TemplateDTO templateDTO, TemplateDirectory parentDirectory) { if (templateEntity instanceof TemplateFile) { TemplateFile templateFile = (TemplateFile) templateEntity; TemplateFileDTO templateFileDTO = (TemplateFileDTO) templateDTO; templateFile.setName(templateFileDTO.getName()); templateFile.setLocalPath(templateFileDTO.getFilePath()); templateFile.setCreatedAt(Instant.now()); if (parentDirectory != null) { parentDirectory.addChildTemplate(templateFile); } else templateFile.setParentDir(null); return templateFile; } else { TemplateDirectory templateDirectory = (TemplateDirectory) templateEntity; TemplateDirectoryDTO templateDirectoryDTO = (TemplateDirectoryDTO) templateDTO; templateDirectory.setName(templateDirectoryDTO.getName()); templateDirectory.setCreatedAt(Instant.now()); templateDirectory.setParent(parentDirectory); Set<TemplateDirectoryDTO> childDirectories = templateDirectoryDTO.getDirectories(); if (childDirectories != null && !childDirectories.isEmpty()) { templateDirectory .setChildDirs(childDirectories .stream() .map(templateDirectoryDTO1 -> createEntityFromTemplateDTO(templateDirectoryDTO1, templateDirectory)) .map(template -> (TemplateDirectory) template) .collect(Collectors.toUnmodifiableSet())); } Set<TemplateFileDTO> childTemplates = templateDirectoryDTO.getTemplates(); if (childTemplates != null && !childTemplates.isEmpty()) { templateDirectory .setChildFiles(childTemplates .stream() .map(templateDTO1 -> createEntityFromTemplateDTO(templateDTO1, templateDirectory)) .map(template -> (TemplateFile) template) .collect(Collectors.toUnmodifiableSet())); } return templateDirectory; } }
我正在尝试通过对 templateFiles 和 templateDirectories 使用存储库方法 findAllByParentIsNull 来显示所有“TemplateTree”:
@Transactional(readOnly = true)
public TemplateTreeDTO getAllTree() {
Set<TemplateFileDTO> rootTemplates =
templateFileRepository.findAllByParentDirIsNull()
.stream()
.map(templateMapper::createTemplateDTOFromEntity)
.map(templateDTO -> (TemplateFileDTO) templateDTO)
.collect(Collectors.toUnmodifiableSet());
Set<TemplateDirectoryDTO> rootTemplateDirectories =
templateDirectoryRepository.findAllByParentIsNull()
.stream()
.map(templateMapper::createTemplateDTOFromEntity)
.map(templateDTO -> (TemplateDirectoryDTO) templateDTO)
.collect(Collectors.toUnmodifiableSet());
TemplateTreeDTO templateTreeDTO = new TemplateTreeDTO();
templateTreeDTO.setTemplates(rootTemplates);
templateTreeDTO.setDirectories(rootTemplateDirectories);
return templateTreeDTO;
}
解决方案
错是我的粗心...在
@Smutje
我发现我实际上并没有在 TemplateDirectoryDTO 中设置模板列表......如此简单明了。希望有人发现这个问题作为 OneToMany 双向关系的示例很有用。
将 TemplateMapper.createTemplateDTOFromEntity 更新为:
public TemplateDTO createTemplateDTOFromEntity(TemplateEntity templateEntity) {
if (templateEntity instanceof TemplateFile) {
TemplateFile templateFile = (TemplateFile) templateEntity;
TemplateFileDTO templateFileDTO = new TemplateFileDTO();
templateFileDTO.setId(templateFile.getId());
templateFileDTO.setName(templateFile.getName());
templateFileDTO.setFilePath(templateFile.getLocalPath());
TemplateDirectory parentDirectory = templateFile.getParentDir();
templateFileDTO.setParentId(parentDirectory == null ? null : parentDirectory.getId());
return templateFileDTO;
} else {
TemplateDirectory templateDirectory = (TemplateDirectory) templateEntity;
TemplateDirectoryDTO templateDirectoryDTO = new TemplateDirectoryDTO();
templateDirectoryDTO.setId(templateDirectory.getId());
templateDirectoryDTO.setName(templateDirectory.getName());
TemplateDirectory parentDirectory = templateDirectory.getParent();
templateDirectoryDTO.setParentId(parentDirectory == null ? null : parentDirectory.getId());
Set<TemplateDirectory> childDirectories = templateDirectory.getChildDirs();
if (childDirectories != null && !childDirectories.isEmpty()) {
templateDirectoryDTO.setDirectories(childDirectories
.stream()
.map(this::createTemplateDTOFromEntity)
.map(templateDTO -> (TemplateDirectoryDTO) templateDTO)
.collect(Collectors.toUnmodifiableSet()));
}
Set<TemplateFile> childFiles = templateDirectory.getChildFiles();
if (childFiles != null && !childFiles.isEmpty()) {
templateDirectoryDTO.setTemplates(childFiles
.stream()
.map(this::createTemplateDTOFromEntity)
.map(templateDTO -> (TemplateFileDTO) templateDTO)
.collect(Collectors.toUnmodifiableSet()));
}
return templateDirectoryDTO;
}
}
缺少的部分是
Set<TemplateFile> childFiles = templateDirectory.getChildFiles();
if (childFiles != null && !childFiles.isEmpty()) {
templateDirectoryDTO.setTemplates(childFiles
.stream()
.map(this::createTemplateDTOFromEntity)
.map(templateDTO -> (TemplateFileDTO) templateDTO)
.collect(Collectors.toUnmodifiableSet()));
}
推荐阅读
- html - href 链接到 index.html 中的组件
- python - 在 anaconda 环境中使用子进程
- android - 如何在 Build.Gradle 中添加 SonarQube 插件并获取当前项目的报告
- java - 我怎样才能得到卷的总和?
- java - 使用 power mockito 模拟静态方法,在其构造函数中返回带有 dao 实例的单例类
- java - Java GUI 在 Thread.sleep 后未启动
- r - 按组值分组的箱线图
- javascript - 如何使用 jquery ajax 发布具有自定义 json 结构的数据?
- python - 如何对两个迭代器“列表”中的值求和?
- jmeter - 如何在 bzm-Parallel 控制器中添加 Post https 请求