cst1992 February 2016

Cannot delete child element in Spring JPA

I'm having problems deleting the child element of a one-to-many relationship entity. Here's a code snippet:

@Override
@Transactional
public void deleteTask(UUID listId, UUID taskId) {
    TaskList list = repo.findOne(listId);

    System.out.println("Old List: " + list);

    for(Task t : list.getTasks()) {
        if(t.getId().toString().equals(taskId.toString())) {
            System.out.println(list.getTasks().remove(t));
            System.out.println("Task with id " + taskId + " deleted.");
        }
    }
    System.out.println("New List: " + repo.save(list));
}

The Task class is this:

@Entity(name = "task")
public class Task implements Serializable {    

    // Id and 3 fields

    @ManyToOne
    @JoinColumn(name="tasklist_id")
    private TaskList parentList;

    // 3 more fields

    // Constructor
    public Task() {}

    //Getters and Setters
}

and the TaskList class is this:

@Entity(name = "task_list")
public class TaskList implements Serializable {

    // Id and two fields

    @OneToMany(mappedBy="parentList", cascade={CascadeType.ALL})
    private List<Task> tasks;

    // Constructor
    public TaskList() {}
}

The Task entity is the child, and even though the save() function returns the truncated TaskList, I can't get the changes to show in a separate query to the database. The number of tasks remains the same. However, deleting a list through repo.delete(listId) works fine with both the list and its tasks gone.

Here, repo is a repository corresponding to the parent TaskList class. All operations to the child Task class happen through a @OneToMany({cascade=CascadeType.ALL}) relation.

For some reason, searching for all TaskLists using repo.findAll() also returns faulty results.

I'm obviously doing so

Answers


Essex Boy February 2016

Here's my task list

@Entity(name = "TASK_LIST")
public class TaskList {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "NAME")
private String name;

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
@JoinColumn(name = "task", referencedColumnName = "id", nullable = false)
private List<Task> tasks = new ArrayList<Task>();

Here's my repository

@Repository
public interface TaskListRepository extends JpaRepository<TaskList, Long> {
}

Here's my test

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext-test.xml")
public class TaskListRepositoryTest {

    @Autowired
    private TaskListRepository repository;

    @Autowired
    private TaskService service;

    @Test
    public void test1() throws SQLException {

        TaskList taskList = new TaskList();
        taskList.getTasks().add(makeTask("name1", "description1"));
        taskList.getTasks().add(makeTask("name2", "description2"));
        taskList.getTasks().add(makeTask("name3", "description3"));
        taskList.getTasks().add(makeTask("name4", "description4"));
        taskList.getTasks().add(makeTask("name5", "description5"));

        service.save(taskList);

        TaskList findOne = repository.findOne(1l);
        assertEquals(5, findOne.getTasks().size());

        taskList.getTasks().remove(2);
        service.save(taskList);

        findOne = repository.findOne(1l);
        assertEquals(4, findOne.getTasks().size());
    }

    @Test
    public void test2() throws SQLException {

        TaskList findOne = repository.findOne(1l);
        assertEquals(4, findOne.getTasks().size());
    }

    private Task makeTask(String name, String description) {

        Task task = new Task();
        task.setName(name);
        task.setDescription(description);
        return task;
    }
 


Jakub Kubrynski February 2016

You need to add orphanRemoval = true to your mapping:

@OneToMany(mappedBy="parentList", cascade={CascadeType.ALL}, orphanRemoval=true)

list.getTasks().remove(t) just removes entity from the collection, so you need to tell JPA to remove it also from DB. This is done by the orphanRemoval attribute.

Post Status

Asked in February 2016
Viewed 2,897 times
Voted 4
Answered 2 times

Search




Leave an answer