我在删除一对多关系实体的子元素时遇到问题。 这是一个代码段:
@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));
}
Task类是这样的:
@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
}
和TaskList类是这样的:
@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() {}
}
Task
实体是子实体,即使save()函数返回截断的TaskList
,我也无法获得要在数据库的单独查询中显示的更改。任务数量保持不变。但是,通过repo.delete(listId)
删除列表可以正常工作,列表及其任务都已消失。
此处,repo
是与父TaskList
类对应的存储库。对孩子Task
课程的所有操作都是通过@OneToMany({cascade=CascadeType.ALL})
关系进行的。
出于某种原因,使用TaskList
搜索所有repo.findAll()
也会返回错误结果。
我显然做了一些根本错误的事情。请告诉我该怎么做。
答案 0 :(得分:4)
您需要在映射中添加orphanRemoval = true
:
@OneToMany(mappedBy="parentList", cascade={CascadeType.ALL}, orphanRemoval=true)
list.getTasks().remove(t)
只是从集合中删除实体,因此您需要告诉JPA也要从DB中删除它。这是由orphanRemoval
属性完成的。
答案 1 :(得分:0)
这是我的任务列表
@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>();
这是我的存储库
@Repository
public interface TaskListRepository extends JpaRepository<TaskList, Long> {
}
这是我的测试
@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;
}