Home > front end >  Deleted item keeps showing in JSON
Deleted item keeps showing in JSON

Time:04-13

I'm working on a simple todo app in which you can add dependencies between todo items which means you cannot change status to true(completed) if dependency item is not completed. The problem is when I delete an item which another item is dependent to, json still shows dependency between two items. I'll try to explain with an example; say you have item 1 and item 2. Item 1 is dependent to item 2 and you can't mark item 1 "completed" if item 2 is not completed. But if you delete item 2 then dependency between items is also gone. So after deleting item 2 I can change item 1's status to true but when I make a get request for item 1, json still shows dependency to item 2.

Here is my TodoItem class;

package com.erdemkara.todoapp.data.entity;

import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonManagedReference;

import javax.persistence.*;
import java.time.LocalDate;
import java.util.Set;

@Entity
@Table(name = "todo_items")
public class TodoItem {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(nullable = false)
    private String name;

    private String description;

    @Column(nullable = false)
    private LocalDate deadline;

    @Column(nullable = false)
    private boolean status;

    @Column(name = "todo_list_id", nullable = false)
    private int todoListId;

    @OneToMany(mappedBy = "todoItem", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JsonManagedReference
    private Set<Dependency> dependencies;

    public TodoItem()
    {}

    public TodoItem(int id, String name, String description, LocalDate deadline,
                    boolean status, int todoListId, Set<Dependency> dependencies)
    {
        this.id = id;
        this.name = name;
        this.description = description;
        this.deadline = deadline;
        this.status = status;
        this.todoListId = todoListId;
        this.dependencies = dependencies;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public LocalDate getDeadline() {
        return deadline;
    }

    public void setDeadline(LocalDate deadline) {
        this.deadline = deadline;
    }

    public boolean isStatus() {
        return status;
    }

    public void setStatus(boolean status) {
        this.status = status;
    }

    @JsonGetter("todo_list_id")
    public int getTodoListId() {
        return todoListId;
    }

    public void setTodoListId(int todoListId) {
        this.todoListId = todoListId;
    }

    public Set<Dependency> getDependencies() {
        return dependencies;
    }

    public void setDependencies(Set<Dependency> dependencies) {
        this.dependencies = dependencies;
    }
}

Dependency class;

package com.erdemkara.todoapp.data.entity;

import com.fasterxml.jackson.annotation.*;
import javax.persistence.*;

@Entity
@Table(name = "dependencies")
public class Dependency {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonIgnore
    private int id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "todo_item_id", nullable = false)
    @JsonBackReference
    private TodoItem todoItem;

    @Column(name = "dependency_item_id", nullable = false)
    private int dependencyItemId;

    public Dependency()
    {}

    public Dependency(int id, TodoItem todoItem, int dependencyItemId)
    {
        this.id = id;
        this.todoItem = todoItem;
        this.dependencyItemId = dependencyItemId;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public TodoItem getTodoItem() {
        return todoItem;
    }

    public void setTodoItem(TodoItem todoItem) {
        this.todoItem = todoItem;
    }

    public int getDependencyItemId() {
        return dependencyItemId;
    }

    public void setDependencyItemId(int dependencyItemId) {
        this.dependencyItemId = dependencyItemId;
    }
}

Response for item 1 get request(item 1 is dependent to item 2 and 3);

{
    "id": 1,
    "name": "Item 1",
    "description": "Study Collections",
    "deadline": "2023-01-09",
    "status": false,
    "dependencies": [
        {
            "dependencyItemId": 3
        },
        {
            "dependencyItemId": 2
        }
    ],
    "todo_list_id": 1
}

I get the same response before and after deleting item 2. But I want to get a response like this;

{
    "id": 1,
    "name": "Item 1",
    "description": "Study Collections",
    "deadline": "2023-01-09",
    "status": false,
    "dependencies": [
        {
            "dependencyItemId": 3
        }
    ],
    "todo_list_id": 1
}

How can I fix this?

EDIT: @Zychoo I use 2 different delete methods on Service layer. One is for deleting all dependencies for an item. The other one is to delete a specific dependency;

public void deleteDependencyByDependencyItemId(int todoItemId, int dependencyItemId) {
    dependencyRepository.deleteByDependencyItemId(todoItemId, dependencyItemId);
}

public void deleteAllDependenciesByTodoItemId(int todoItemId) {
    dependencyRepository.deleteAll(dependencyRepository.findAllByTodoItemId(todoItemId));
}

And this is the Repository Layer;

public interface IDependencyRepository extends CrudRepository<Dependency, Integer> {
    @Modifying
    @Transactional
    @Query(value = "delete from dependencies d where d.todo_item_id=? and d.dependency_item_id =?", nativeQuery = true)
    void deleteByDependencyItemId(int todoItemId, int dependencyItemId);
}

CodePudding user response:

You could changed

public Set<Dependency> getDependencies() {
    return dependencies;
}

to

 public Set<Dependency> getDependencies() {
     return dependencies.stream().filter(dependency -> "your condition for completion").collect(Collectors.toSet());
 }

The ObjectMapper from spring-boot uses the getters to create a JSON. If your Dependency does not show up in the return value of your getter, it will not show up in the JSON response.

CodePudding user response:

I reorganized delete method in TodoItem service layer from this:

public void deleteItemById(int id) {
    todoItemRepository.deleteById(id);
}

to this:

public void deleteItemById(int id) {
    todoItemRepository.deleteById(id);
    dependencyService.deleteAllDependenciesByTodoItemId(id);
}

It deletes every dependency along with the item. Now it works as I expected. Thank you for the answers.

  • Related