0

I want to create Organization Structure using JPA. If I insert data using my controller, it will throw a PSQLException because the first node's parent is null. But if I input the first node manually into DB, it works for the next node. I read about this and other postings but no luck for me.

This is my entity:

@Entity
@Table(name = "tree")
public class Node implements Serializable {
@Id
private int id;
private String name;

@OneToMany(
        cascade = CascadeType.ALL
)
@JoinColumn(name = "parent_id", nullable = true)
@OrderColumn
@JsonManagedReference
private Set<Node> children = new HashSet<>();

@Basic(optional = true)
@ManyToOne(
        fetch = FetchType.LAZY,
        optional = true
)
@JoinColumn(name = "parent_id", nullable = true)
@JsonBackReference
private Node parent;

public void addNode(Node node){
    this.getParent().getChildren().add(node);
    node.setParent(this.getParent());
}

// Getter setter was removed for brevity
}

This is my controller:

@RestController
@RequestMapping("/node")
public class NodeController {
@Autowired
private NodeRepository nodeRepository;

@GetMapping
public @ResponseBody Iterable<Node> index(){
    return nodeRepository.findByParentIsNull();
}

@PostMapping
public String add(
        @RequestBody List<Node> nodes){

        nodes.stream().forEach(
                node -> {
                    node.addNode(node);
                }
        );

        nodeRepository.saveAll(nodes);
        return "nice";
     }
}

And, this is my data sample:

[
 {
   "id":8,
   "name":"Top Parent",
   "parent":{}
 },{
   "id":9,
   "name":"Node 1",
   "parent":{
      "id":8
    }
 },{
   "id":10,
   "name":"Node 2",
   "parent":{
      "id":8
    }
 },{
   "id":11,
   "name":"Node 3",
   "parent":{
      "id":9
    }
 }
]

The Expected Result after inserting via controller is:

id    |name       |parent_id
===========================
8     |Top Parent |null
9     |Node 1     |8
10    |Node 2     |8
11    |Node 3     |9

Let me know if something unclear. Thank in advance!

1 Answers1

0

I find a workaround for my problem. So, I put here if someone faces a similar problem with me. I added a NativeQuery in my repository like this:

@Query(value = "insert into tree values(:id,:name)", nativeQuery = true)
void saveTop(@Param("id")int id,@Param("name")String name);

And then I added some lines in my controller like this:

@PostMapping("/top")
public void addTop(@RequestBody Node node){
    nodeRepository.saveTop(node.getId(),node.getName());
}

Basically, I create an endpoint("/node/top") to insert top node for my structure organization tree manually.