简体   繁体   中英

How to delete child records using Spring Data JPA

I am having alot of issues trying to delete child records using JPA. Consider the mappings below. I am trying to delete all the state data in the jobs table. When it is removed it will cascade all deletes down the chain. Here is the chain:

Job -> State -> TaskState -> Step

When I try to remove state from job table it is set to NULL. However it is not cascaded down the chain. How would I go about achieving this?

Here is how I am deleting the data:

@Transactional
public void runJob(Long id) throws IOException, JAXBException {

        Job job = jobRepository.findOne(id);

        if(job.getState() != null){
            State stateObj = stateRepository.findOne(job.getState().getId());
            stateObj.setTasks(null);
            stateRepository.delete(stateObj);
        }

        job.setState(null);
        jobRepository.save(job);
}

Jobs:

@Entity
@Table(name = "jobs")
public class Job implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;
    @Column(name = "name")
    private String name;
    @Column(name = "description")
    private String description;
    @Temporal(TemporalType.TIMESTAMP)
    private Date date;
    @OneToOne
    private Image image;
    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
    private State state;
    @OneToMany
    private List<Task> tasks;
    @Column(name = "status")
    @Enumerated(EnumType.STRING)
    private JobStatusEnum status;
    @ManyToMany
    private List<Device> devices;
    @OneToMany
    private List<JobRun> runs;
    @OneToMany
    private List<Container> containers;

    public Job() {
        this.image = new Image();
        this.status = JobStatusEnum.New;
        this.devices = new ArrayList<>();
        this.runs = new ArrayList<>();
        this.containers = new ArrayList<>();
    }

    public Job(String name, String description, Date date, Image image, State state, List<Task> tasks, JobStatusEnum status, List<Device> devices, List<JobRun> runs, List<Container> containers) {
        this.name = name;
        this.description = description;
        this.date = date;
        this.image = image;
        this.state = state;
        this.tasks = tasks;
        this.status = status;
        this.devices = devices;
        this.runs = runs;
        this.containers = containers;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long 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 Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Image getImage() {
        return image;
    }

    public void setImage(Image image) {
        this.image = image;
    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    public List<Task> getTasks() {
        return tasks;
    }

    public void setTasks(List<Task> tasks) {
        this.tasks = tasks;
    }

    public JobStatusEnum getStatus() {
        return status;
    }

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

    public List<Device> getDevices() {
        return devices;
    }

    public void setDevices(List<Device> devices) {
        this.devices = devices;
    }

    public List<JobRun> getRuns() {
        return runs;
    }

    public void setRuns(List<JobRun> runs) {
        this.runs = runs;
    }

    public List<Container> getContainers() {
        return containers;
    }

    public void setContainers(List<Container> containers) {
        this.containers = containers;
    }
}

State:

@Entity
@Table(name = "state")
public class State implements Serializable {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name="name")
    private String name;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<TaskState> tasks;

    public State() {
        tasks = new ArrayList<>();
    }

    public State(Long id, String name, List<TaskState> tasks) {
        this.id = id;
        this.name = name;
        this.tasks = tasks;
    }

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public List<TaskState> getTasks() {
        return tasks;
    }

    public void setTasks(List<TaskState> tasks) {
        this.tasks = tasks;
    }
}

TaskState:

@Entity
@Table(name = "task_state")
public class TaskState implements Serializable {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "parent")
    private Long parent;
    @Column(name = "referenceid")
    private Long referenceId;
    @Column(name = "name")
    private String name;
    @Column(name = "status")
    private TaskStatusEnum status;
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<Step> steps;
    @Column(name = "maxAttempts")
    private Integer maxAttempts;
    @ManyToOne
    @JsonIgnore
    private State state;

    public TaskState() {
        status = TaskStatusEnum.New;
        steps = new ArrayList<>();
        maxAttempts = 5;
    }

    public TaskState(Long id, Long parent, Long referenceId, String name, TaskStatusEnum status, List<Step> steps, Integer maxAttempts) {
        this();
        this.id = id;
        this.parent = parent;
        this.referenceId = referenceId;
        this.name = name;
        this.status = status;
        this.steps = steps;
        this.maxAttempts = maxAttempts;
    }

    public Long getId() {
        return id;
    }

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

    public Long getParent() {
        return parent;
    }

    public void setParent(Long parent) {
        this.parent = parent;
    }

    public String getName() {
        return name;
    }

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

    public TaskStatusEnum getStatus() {
        return status;
    }

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

    public List<Step> getSteps() {
        return steps;
    }

    public void setSteps(List<Step> steps) {
        this.steps = steps;
    }

    public Long getReferenceId() {
        return referenceId;
    }

    public void setReferenceId(Long referenceId) {
        this.referenceId = referenceId;
    }

    public Integer getMaxAttempts() {
        return maxAttempts;
    }

    public void setMaxAttempts(Integer maxAttempts) {
        this.maxAttempts = maxAttempts;
    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }
}

Step:

@Entity
@Table(name = "step")
public class Step implements Serializable {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "name")
    private String name;
    @Column(name = "groupname")
    private String group;
    @Column(name = "route")
    private String route;
    @Column(name = "celerytask")
    private String celeryTask;
    @Column(name = "postbackqueuename")
    private String postBackQueueName;
    @Column(name = "postbackerrorqueuename")
    private String postBackErrorQueueName;
    @Enumerated(EnumType.STRING)
    @Column(name = "status")
    private TaskStatusEnum status;
    @ElementCollection
    private List<String> arguements;
    @Column(name="runningTaskId")
    private Long runningTaskId;
    @Column(name="result")
    private String result;
    @Column(name="attempt")
    private Integer attempt;
    @JsonIgnore
    @ManyToOne
    private TaskState task;

    public Step() {
        arguements = new ArrayList<>();
        status = TaskStatusEnum.New;
        attempt = 0;
    }

    public Step(String name, String group, String route, String celeryTask, String postBackQueueName, String postBackErrorQueueName, TaskStatusEnum status, List<String> arguements, Long runningTaskId) {
        this();
        this.name = name;
        this.group = group;
        this.route = route;
        this.celeryTask = celeryTask;
        this.postBackQueueName = postBackQueueName;
        this.postBackErrorQueueName = postBackErrorQueueName;
        this.status = status;
        this.arguements = arguements;
        this.runningTaskId = runningTaskId;
    }

    public String getName() {
        return name;
    }

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

    public String getGroup() {
        return group;
    }

    public void setGroup(String group) {
        this.group = group;
    }

    public String getRoute() {
        return route;
    }

    public void setRoute(String route) {
        this.route = route;
    }

    public String getCeleryTask() {
        return celeryTask;
    }

    public void setCeleryTask(String celeryTask) {
        this.celeryTask = celeryTask;
    }

    public String getPostBackQueueName() {
        return postBackQueueName;
    }

    public void setPostBackQueueName(String postBackQueueName) {
        this.postBackQueueName = postBackQueueName;
    }

    public String getPostBackErrorQueueName() {
        return postBackErrorQueueName;
    }

    public void setPostBackErrorQueueName(String postBackErrorQueueName) {
        this.postBackErrorQueueName = postBackErrorQueueName;
    }

    public List<String> getArguements() {
        return arguements;
    }

    public void setArguements(List<String> arguements) {
        this.arguements = arguements;
    }

    public TaskStatusEnum getStatus() {
        return status;
    }

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

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public Integer getAttempt() {
        return attempt;
    }

    public void setAttempt(Integer attempt) {
        this.attempt = attempt;
    }

    public Long getId() {
        return id;
    }

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

    public Long getRunningTaskId() {
        return runningTaskId;
    }

    public void setRunningTaskId(Long runningTaskId) {
        this.runningTaskId = runningTaskId;
    }

    public TaskState getTask() {
        return task;
    }

    public void setTask(TaskState task) {
        this.task = task;
    }
}

It's not cascading because of stateObj.setTasks(null); .

You're breaking the link between the State and its Tasks so when you're deleting the State, the delete doesn't cascade on anything.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM