为什么hibernate在逐出后更新数据库

时间:2016-06-30 03:25:07

标签: java hibernate

我有两个相关的参与者:

@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无关。

1 个答案:

答案 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查询的原因。

会话被设计为基于工作单元的接口,有充分的理由 - 事务语义将是没有此功能的灾难。如果您需要刷新单个实体而不刷新属于同一会话的其他实体,则需要重新考虑您的工作单元。

相关问题