我有FetchType.LAZY和hibernate对象仍然加载

时间:2013-02-23 23:28:59

标签: hibernate lazy-loading hibernate-mapping eager-loading

我在“角色”实体中有这种关系

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "persona")
private Empleado empleado;

在我的“ Empleado ”实体中,我有这种关系

@OneToMany(cascade = CascadeType.ALL, mappedBy = "empleado", fetch = FetchType.EAGER)
private Set<Trabajo> trabajos = new HashSet<Trabajo>();

我在“ Trabajo ”实体中有这种关系

@BatchSize(size = 100)
@OneToMany(cascade = CascadeType.ALL, mappedBy = "trabajo", fetch = FetchType.LAZY)
private Set<Atencion> atenciones = new HashSet<Atencion>();

这个登录方法由GoogleCode提供

@Override
public Persona acceder(String login, String password) {
    Search s = new Search();
    s.addFilterEqual("usuario", login);
    s.addFilterEqual("clave", password);
    return searchUnique(s);
}

当我获得结果对象时,它已经加载了具有EAGER fecth的对象,一切正常,除了在“ Trabajo ”实体中“ Atenciones ”集合获得加载它有LAZY fetch。我该如何解决这个问题?

在我的Trabajo实体中,我有其他具有LAZY提取功能的@OneToMany关系,但仍然会得到加载对象,我不知道为什么。

当我使用dozer mapperService时,它映射了所有整个树对象,我可以看到所有不应出现的对象。

2 个答案:

答案 0 :(得分:3)

延迟加载并不意味着不会加载数据。这意味着只有当您(或Dozer,在这种情况下)询问其值时才会加载数据。

假设您有一个实体管理器,OneToMany具有实体Worker。并假设该关联是懒惰的。这是将要发生的事情:

Manager manager = session.get(Manager.class, 1L); 
// the above line loads the manager data from the database, using a SQL query

List<Worker> workers = manager.getWorkers();
// the workers variable references a Hibernate-specific list which is lazy-loaded.
// It doesn't contain any data until a method is called on it

int size = workers.size();
// calling any method of the list will cause a SQL query to be executed. This
// SQL query will load the workers of the manager from the database, and fill the list
// finally, the size of the list will be returned.

这很懒,因为它只在您真正需要时加载。

因此,如果您不希望在使用Dozer映射它时使用管理器返回工作程序,请确保Dozer不会尝试获取工作程序。有两种简单的解决方案可以做到这一点:

  • 不要使用Dozer(吮吸,恕我直言)
  • Manager实体映射到不包含工作人员列表的ManagerDTO类。

答案 1 :(得分:0)

关于延迟加载here有一个很好的解释。您所看到的可能是代理对象。检查sql被激活以验证数据是否真的从db加载。如果没有与'Atencion'相关的表上的查询,请不要担心

您的推土机映射可能正在访问导致从db加载的记录的'atenciones'元素。如果您不希望这种情况发生,应该有一种方法可以从映射中排除某些字段。