Ant*_*met 2 java spring hibernate jpa
我有一个简单的设置有两个对象,Event而Task其链接为父子和默认JPA库对于一些CRUD操作.我做了一个测试,我把2连接Task到一个Event,然后我尝试delete在其中一个上调用一个动作Task,它失败了(没有错误,也没有删除).
如果我运行相同的测试不添加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);
}
Run Code Online (Sandbox Code Playgroud)
而且测试:
@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());
}
Run Code Online (Sandbox Code Playgroud)
更新:如果我删除fetch = FetchType.EAGER从@OneToMany在上Event类,它的工作原理.虽然知道原因仍然很好.以下是我的新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;
}
Run Code Online (Sandbox Code Playgroud)
JPA规范的相关摘录:
第3.2.4节:
应用于实体X的刷新操作的语义如下:
- 如果X是托管实体,则会将其同步到数据库.
- 对于来自X的关系引用的所有实体Y,如果与Y的关系已使用级联元素值cascade = PERSIST或cascade = ALL进行注释,则将持久化操作应用于Y
第3.2.2节:
应用于实体X的持久化操作的语义如下:
- 如果X是已删除的实体,则它将被管理.
那么,你的情况是怎么回事:
Task.Event实例.没有变化,但PERSIST操作级联到tasks.PERSIST应用于集合Task中的所有s tasks,包括已删除的s ,它将再次被管理.要验证这一点,请启用包的TRACE日志级别org.hibernate并搜索包含的邮件un-scheduling entity deletion.
如果tasks是懒惰加载,PERSIST则不应用于它们(如果集合在此期间没有初始化,当然); 这就是为什么在这种情况下你没有看到这种行为的原因.
解决的办法是删除从已删除任务Event的tasks集合也使PERSIST不适用于它.
| 归档时间: |
|
| 查看次数: |
1492 次 |
| 最近记录: |