JPA对同一实体的循环依赖导致递归输出
Posted
技术标签:
【中文标题】JPA对同一实体的循环依赖导致递归输出【英文标题】:JPA Circular dependency on same entity resulting in recursive output 【发布时间】:2018-08-24 06:14:01 【问题描述】:我有一个文件夹类,它又可以有许多子文件夹。在这种情况下,我试图使用单个实体来实现相同的实体。
如下所示。
Folders
----SubFolder
----SubFolder
以下是课程。
FolderData.java
@Entity
@JsonIdentityInfo(generator =ObjectIdGenerators.IntSequenceGenerator.class,property="projectId")
public class FolderData
@Id
@SequenceGenerator(name = "seq-gen", initialValue = 1)
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "seq-gen")
private Integer parentId;
private int moduleId;
private int subProjectId;
private String folderName;
private Integer folderId;
private int projectId;
@ManyToOne(fetch = FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name="folder_child")
@JsonIgnore
private FolderData folderData;
@OneToMany(mappedBy = "folderData")
@JsonIgnoreProperties("folderList")
private Set<FolderData> folderList=new HashSet<>();
FodlerController.java
@RestController
@RequestMapping("/folder")
public class FodlerController
@Autowired
private FolderService folderService;
@GetMapping(produces = "application/json")
public List<FolderData> getFolderList()
return folderService.findAllFromTheList();
@PostMapping(produces = "application/json", consumes = "application/json")
public void createFolder(@RequestBody FolderData folderData)
if(folderData.getId()==null && folderData.getFolderId()==null)
System.out.println("id is null");
folderData.setFolderId(new Random().nextInt());
folderService.save(folderData);
else
folderService.doChildAddition(folderData);
FolderService.java
@Service
public class FolderService
@Autowired
private FolderRepo folderRepo;
public FolderData save(FolderData folderData)
return folderRepo.save(folderData);
public FolderData getFolderDataByParentId(Integer id)
return folderRepo.getOne(id);
public List<FolderData> findAllFromTheList()
return folderRepo.findAll();
public FolderData getFolderDataByfolderId(Integer folderId)
return folderRepo.findFolderByFolderId(folderId);
public void doChildAddition(FolderData childFolder)
FolderData parentFolder=folderRepo.findFolderByFolderId(childFolder.getFolderId());
childFolder.setFolderData(parentFolder);
FolderData childFolderSaved = folderRepo.saveAndFlush(childFolder);
//parentFolder.getFolderList().add(folderRepo.getOne(childFolderSaved.getId()));
//folderRepo.save(parentFolder);
创建父级的 Json 请求和收集到的响应,其中包括自动生成的文件夹 ID:
"moduleId":1,
"subProjectId":1,
"folderName":"One",
"projectId":1
[
"projectId": 0,
"moduleId": 1,
"subProjectId": 1,
"folderName": "One",
"folderId": 963031296,
"folderList": [],
"id": 1
]
为父级创建子级并收集响应。
"moduleId":1,
"subProjectId":2,
"folderName":"Two",
"projectId":1,
"folderId": -963031296
[
"projectId": 0,
"moduleId": 1,
"subProjectId": 1,
"folderName": "One",
"folderId": 963031296,
"folderList": [
"projectId": 0,
"moduleId": 1,
"subProjectId": 2,
"folderName": "Two",
"folderId": 963031296,
"id": 2
],
"id": 1
,
2
]
对于上述响应,由于我使用的是响应,因此我得到了第 2 位
@JsonIdentityInfo(generator =ObjectIdGenerators.IntSequenceGenerator.class,property="parentId")
否则整个对象会出现而不是 2。
如果我没有使用 JsonIdentityInfo 的示例输出
[
"projectId": 0,
"moduleId": 1,
"subProjectId": 1,
"folderName": "One",
"folderId": 963031296,
"folderList": [
"projectId": 0,
"moduleId": 1,
"subProjectId": 2,
"folderName": "Two",
"folderId": 963031296,
"id": 2
],
"id": 1
,
"projectId": 0,
"moduleId": 1,
"subProjectId": 2,
"folderName": "Two",
"folderId": 963031296,
"id": 2
]
【问题讨论】:
Prash,恐怕你没写问题。 @JánHalaša,已编辑请给我同样的建议。 【参考方案1】:这很容易,@Prash
由于您在单向依赖项中使用了Set
,因此您必须提供连接(依赖)实体的唯一性。任何集合都使用hashCode()
和equals()
来确定要添加的并发项目的可用性。您的 FolderData
类没有 hashCode()
和 equals()
所以从 JVM 的角度来看,所有反序列化的对象都是相同的,并且由于 Set
的性质,只保留最后一个示例是正常的
【讨论】:
以上是关于JPA对同一实体的循环依赖导致递归输出的主要内容,如果未能解决你的问题,请参考以下文章