java Spring引导休眠:无法单独删除子对象
我有一个简单的设置,有两个对象,Event
和Task
,它们作为父子对象链接,还有一个用于某些CRUD操作的默认JPA存储库。我做了一个测试,将2Task
附加到一个Event
上,然后尝试对其中一个Task
调用一个delete
操作,该操作失败(没有错误,也没有删除)
如果我运行相同的测试,而没有将Task
添加到Event
,则操作成功。下面是我所有的代码,关于我下一步需要做什么有什么想法吗
@Entity
public class Event {
@Id
@GeneratedValue(generator = "hibernate-uuid")
@GenericGenerator(name = "hibernate-uuid", strategy = "uuid2")
@Column(unique = true)
String id;
String subject;
@OneToMany(mappedBy="event", cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
@JsonIgnoreProperties({"event"})
List<Task> tasks;
}
@Entity
public class Task {
@Id
@GeneratedValue(generator = "hibernate-uuid")
@GenericGenerator(name = "hibernate-uuid", strategy = "uuid2")
@Column(unique = true)
String id;
String subject;
@ManyToOne
@JsonIgnoreProperties({"tasks"})
Event event;
}
public interface TaskRepository extends JpaRepository<Task, String> {
public Task findById(String id);
}
以及测试:
@Test
public void testSequenceOfActionsOnEventWithSubtasks() {
// Save a new task
Task savedTask = given()
.body(
new TaskBuilder()
.subject("Previously saved task")
.build()
).contentType(ContentType.JSON)
.when().post(TASKS_RESOURCE).as(Task.class);
Task unsavedTask = new TaskBuilder()
.subject("Unsaved task")
.build();
// Save a new event with an unsaved and a saved task attached
Event savedEvent = given()
.body(
new EventBuilder()
.subject("Main event")
.addTask(savedTask)
.addTask(unsavedTask)
.build()
).contentType(ContentType.JSON)
.when().post(EVENTS_RESOURCE).as(Event.class);
// Make sure the event now contains two tasks with GUID's attached
List<Task> tasksForEvent = when().get(EVENT_RESOURCE, savedEvent.getId()).as(Event.class).getTasks();
assertEquals(2, tasksForEvent.size());
// Get all tasks, make sure firstTask is in there
when().get(TASKS_RESOURCE).then().body(SUBJECT_FIELD, hasItems(savedTask.getSubject()));
// Delete a task that was attached to the event
when().delete(TASK_RESOURCE, savedTask.getId()).then().statusCode(HttpStatus.SC_OK);
// Get all tasks, make sure firstTask is NOT in there
when().get(TASKS_RESOURCE).then().body(SUBJECT_FIELD, not(hasItems(savedTask.getSubject())));
// Check the event again
tasksForEvent = when().get(EVENT_RESOURCE, savedEvent.getId()).as(Event.class).getTasks();
assertEquals(1, tasksForEvent.size());
}
更新:如果我从Event
类中的@OneToMany
上删除fetch = FetchType.EAGER
,它会工作。不过,我还是想知道原因。下面是我的新Event
类
@Entity
public class Event {
@Id
@GeneratedValue(generator = "hibernate-uuid")
@GenericGenerator(name = "hibernate-uuid", strategy = "uuid2")
@Column(unique = true)
String id;
String subject;
@OneToMany(mappedBy="event", cascade = { CascadeType.ALL })
@JsonIgnoreProperties({"event"})
List<Task> tasks;
}
# 1 楼答案
来自JPA specification的相关摘录:
第3.2.4节:
第3.2.2节:
那么,你的情况如何:
Task
李>Event
实例。它没有变化,但是PERSIST
操作被级联到tasks
李>PERSIST
应用于tasks
集合中的所有Task
,包括已删除的,该集合将再次被管理李>要验证这一点,请为
org.hibernate
包启用TRACE
日志级别,并搜索包含un-scheduling entity deletion
的消息如果
tasks
是延迟加载的,那么PERSIST
不会应用于它们(当然,如果集合在此期间没有初始化);这就是为什么在这种情况下你看不到这种行为解决方案是从
Event
的tasks
集合中删除已删除的任务,这样PERSIST
就不会应用于它# 2 楼答案
add=true属性