Reputation: 295
I can't seem to come up with a solution to my recursion problem. So I have this Version object that holds a list of references to other version objects it is dependent on.
Version
{
"id": "id1",
"version": "1",
"dependencies": [
{
"id": "id2"
},
{
"id": "id3"
}
]
}
When I retrieve this object I also have to retrieve it's dependencies as well the dependency's dependencies until there is an eventual end, which would look something like this
VersionDto
{
"id": "id1",
"version": "1",
"dependencies": [
{
"id": "id2",
"version": "2",
"dependencies": [
{
"id": "id4",
"version": "4",
"dependencies": []
}
]
},
{
"id": "id3",
"version": "3",
"dependencies": []
}
]
}
This is my Recursive function to retrieve a version
public VersionDto getVersion(String id)
{
//Retrieves from database
Version version = versionDAO.getVersion(id);
//Convert to Dto (basic fields)
VersionDto versionDto = new VersionDto(version);
//Recursivly retrieve dependencies
for (Map<String, String> dep : version.getDependencies()) {
VersionDto dto = new VersionDto();
//Recursive call
dto = getVersion(dep.get("id"));
versionDto.getDependencies().add(dto);
}
return versionDto;
}
However I run into the problem of a possible infinite loop in the case where a version could be a dependency to one of the nested dependencies such that v1 -> v2 -> v4 -> v1 causing a infinite repeat.
Any idea how I could solve and prevent this infinite loop, so that if the version all ready occurred earlier it should just skip it?
Edit: Solution using global list
public VersionDto getVersion(String id)
{
//Check global list contains version
if (visited.contains(id)) {
return null;
}
visited.add(docId);
//Retrieves from database
Version version = versionDAO.getVersion(id);
//Convert to Dto (basic fields)
VersionDto versionDto = new VersionDto(version);
//Recursivly retrieve dependencies
for (Map<String, String> dep : version.getDependencies()) {
VersionDto dto = new VersionDto();
//Recursive call
dto = getVersion(dep.get("id"));
if(dep!= null) {
versionDto.getDependencies().add(dto);
}
}
return versionDto;
}
Upvotes: 0
Views: 6564
Reputation: 80
The infinite recursive loop problem can be very efficiently solved using Jackson libraries. The Jackson libraries comes in handy, particularly, if you are using Hibernate/JPA for persistence. Namely, the @JsonManagedReference and @JsonBackReference annotations would apply to your case.
You have not shown your JPA Entity code, so I can't tell you where exactly you should put these annotations. But, a good example of how to use them is available at
http://springquay.blogspot.com/2016/01/new-approach-to-solve-json-recursive.html
Hope you find it useful!
Upvotes: 1
Reputation: 151
hope this helps.
if the dependency of v1 is going to be same always then it works.
dto = getVersion(dep.get("id"));
//check if the versionDto contains the dependecy already then break the loop here
versionDto.getDependencies().add(dto);```
Upvotes: 1
Reputation: 861
The best way to be sure that the recursive functions will end, is to put one, or more conditions. You must have one, to make sure that it won't go in an infinite loop.
I would suggest to make an array or a list, where you store all the already visited nodes, so when running the recursive function you can be aware that you have already visited a node, and can move to another one.
Upvotes: 1