防止Hibernate加载延迟的ManyToOne

时间:2014-07-15 12:39:59

标签: java hibernate jpa orm hibernate-mapping

我将问题减少到我的模型中的3个实体:

  • 站。
  • 地点(每站几个)。
  • 位置组(每个站点几个)。

Location类:

@Entity
@Table(name = "***")
public class Location {

   @ManyToOne
   @JoinColumn(name = "s_id")
   private Station s;

   @ManyToOne
   @JoinColumn(name = "g_id")
   private GroupOfLocations group;      

 }

GroupOfLocation的课程:

@Entity
@Table(name = "***")
public class GroupOfLocation {

  @ManyToOne(fetch = FetchType.LAZY) //I do not want the Station to be loaded
  @JoinColumn(name = "s_id")
  private Station s;

}

当我按ID获取位置时:

  1. 其电台已装载
  2. 已加载位置信息组
  3. 群组的网站已加载我不需要它。
  4. 问题:该论坛包含电台,但我不希望它被加载。我预计fetch = FetchType.LAZY会阻止Station完全加载,但它不起作用。

    我搜索了SO,有时,问题来自声明为final的类,但此模型中没有最终类。

    有什么想法吗?

    这是ID:

    搜索的实体ID的方式
    public Location getById(Integer id) {
      CriteriaBuilder cb = em.getCriteriaBuilder();
      CriteriaQuery<Location> query = cb.createQuery(Location.class);
      Root<Location> entity = query.from(Location.class);
      Predicate whereClause = cb.equal(entity.get(Location_.id), id);
      query.where(whereClause); 
      return em.createQuery(query).getSingleResult();
    }
    

2 个答案:

答案 0 :(得分:1)

任何JPQL或Criteria查询都将转到override the default获取计划(您在实体映射中定义的计划)。

默认查询计划仅在使用find或getReference

加载实体时有效
entityManager.find(GroupOfLocation.class, 1L);

默认的@ManyToOne提取是EAGER,但由于您还没有发出连接提取,因此会通过一些额外的选择来提取这些提取。

location.group.station 无法通过其他选择获取,但代理仍然存在。

如果 location.station 恰好与 location.group.station 匹配,那么Hibernate将使用已经加载的location.station,因为在Hibernate Session对象内部相等匹配实例相等(意味着只能有一个具有给定实体标识符的实体类型的对象)。

因此,如果 location.group.station location.station 引用同一实体,您将看到初始化的代理,否则代理将保持未初始化。< / p>

如果会话已关闭且代理服务器未初始化,则访问时会出现Lazy异常。

答案 1 :(得分:0)

但你没有在s&amp; s上声明fetch = FetchType.LAZY。地点的集团财产。