Q:

Spring boot + (JPA) - Category hierarchy - recursively traverse

I have Catalog Entity - 
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column
private String categoryName;

@ManyToOne
@JoinColumn(name = "parent_id")
private Category parent;

@OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE, orphanRemoval = true)
private List<Category> children = new ArrayList<Category>();

@ManyToMany(mappedBy = "categories")
private Set<Product> 

And records in the table :
id,  category_name,   parent_id
'1', 'HOME',            NULL
'2', 'Category 1',       '1'
'3', 'Category 2',       '1'
'4', 'Sub-Category 1',   '2'
'5', 'Sub-Category 1 2', '2'

And some methods in the controller (in my case but the questions is principle)
List<Category> categoryList = categoryRepository.findAll();

    for (Category cat : cateList) {
        recursiveTree(cat);
    }

public void recursiveTree(Category cat) {
        System.out.println(cat.getCategoryName());
        if (cat.getChildren().size() > 0) {
            for (Category c : cat.getChildren()) {
                recursiveTree(c);
            }
        }
    }

When i run this, in the console i get - 
HOME
Category 1
Sub-Category 1
Sub-Category 1 2
Category 2
Category 1
Sub-Category 1
Sub-Category 1 2
Category 2
Sub-Category 1
Sub-Category 1 2

How can i modify the recursion, so i can get the proper order of categories and subcategories? I can't figure out why i get some duplicates data

A:

You get duplicate data because you are fetching all Categories from the database with List<Category> categoryList = categoryRepository.findAll();
This list contains HOME, Category 1, Category 2, ...
Since for each item of this list you call the recursiveTree method in your main loop, you will print the tree for HOME (which will thus print all its children), you will also call recursiveTree for Category 1, printing that category and its children again, and so forth.
If you want each category printed only once, only look up the root categories (HOME and any others without parent you may have) and call recursiveTree for those. For example:
List<Category> rootCategoryList = categoryRepository.findByParentIsNull();
for (Category cat : rootCategoryList) {
    recursiveTree(cat);
}

