我有两个相关的参与者:
@Entity
@DynamicUpdate(true)
public class DreamTaskInfo {
private DreamInfo dreamInfo;
@ManyToOne
@JoinColumn(name = "DREAM_INFO_ID", nullable = false)
public DreamInfo getDreamInfo() {
return dreamInfo;
}
...
}
@Entity
@DynamicUpdate(true)
public class DreamInfo {
private Set<DreamTaskInfo> dreamTasks = new LinkedHashSet<>();
@OneToMany(mappedBy = "dreamInfo",cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@OrderBy("remindTime")
public Set<DreamTaskInfo> getDreamTasks() {
return dreamTasks;
}
...
}
我想使用来自DB的DreamTaskInfo数据进行只读使用,所以我这样做:
DreamTaskInfo task = this.get(id);//query from db
getSession().evict(task);//getSession().contains(task)==false
但我发现Hibernate总是在刷新时执行此任务的更新sql。 最后,我使用getSession()。clear()而不是evict,它可以工作。 也许热切地获取或关联导致会话中的某些内容? 实际上我并不是手动修改任何内容而是自动更新hibernate,因此它与question无关。
答案 0 :(得分:0)
你必须在调用evict()之前刷新会话。然后你不会看到在evict()之后运行更新查询。
解决方案:
DreamTaskInfo task = this.get(id);//query from db
getSession().flush();// to make sure atomicity of session is maintained
getSession().evict(task);//getSession().contains(task)==false
从数据库中获取对象后可能会有一些更改,这就是hibernate将运行Update查询的原因。
会话被设计为基于工作单元的接口,有充分的理由 - 事务语义将是没有此功能的灾难。如果您需要刷新单个实体而不刷新属于同一会话的其他实体,则需要重新考虑您的工作单元。