java – JPA Hibernate Lazy多对一提取代理

我正在使用JPA 2.1和Hibernate 4.3.7

我试图调整我的应用程序,所以我将关系变为懒惰,只获取我需要的东西

我有多对一关系的问题,当我再次加载实体时转向懒惰Hibernate通过代理替换实体即使我获取实体并且此代理不在视图部分(JSF)中工作应用程序.
当多对一处于急切模式时,问题会消失,但即使我不需要它们,休眠也会为每个多对一执行一个选择

@Entity
public class Department {
    @Id
    private Integer id;

    //...
}

1 /

@Entity
public class Employee {
    @Id
    private Integer id;

    @ManyToOne(fetch = FetchType.LAZY, optional = true)
    @JoinColumn(name = "id_department", referencedColumnName = "id")
    private Department department;

    //...
}

JPQL查询:

SELECT e FROM Employee e LEFT JOIN FETCH e.department WHERE e.id=:id

=>一个选择查询=>更快但部门类型为Department _ $$_ jvst3ac_5f(employee.getDepartment().getClass().getCanonicalName())并且此代理在应用程序的视图部分不起作用

2 /

@Entity
public class Employee {
    @Id
    private Integer id;

    @ManyToOne(fetch = FetchType.EAGER, optional = true)
    @JoinColumn(name = "id_department", referencedColumnName = "id")
    private Department department;

    //...
}

JPQL查询:

SELECT e FROM Employee e WHERE e.id=:id

=>两个选择=>较慢但部门作为部门加载,一切都在应用程序的视图部分正常

这种关系是单向的,Department没有提及emplyees

使用FETCH JOIN时,这可能是没有代理的部门吗?

在Luiggi的响应之后,我将使用懒惰的多对一提取连接来提取数据.当我做employee.getDepartment().toString()时我有Department {id = 11,…}但是这个部门的类仍然是Department _ $$_ jvst3ac_5f.由于我不知道,即使获取数据,JSF / PrimeFaces selectOneMenu组件也无法正常运行HibernateProxy

除了@ManyToOne(fetch = FetchType.LAZY)之外,我还尝试使用Hibernate注释@LazyToOne(LazyToOneOption.FALSE),但结果类似于@ManyToOne(fetch = FetchType.EAGER)…

最佳答案 问题是,当您使用延迟加载时,您将获得该类的代理(如您所述),并且只有在hibernatesession仍处于打开状态时,此代理才能从数据库中获取数据.在将数据返回到视图时,似乎关闭了会话,因此在尝试使用视图中的延迟加载字段时,您将获得异常.

可能的解决方案:

>保持字段为fetch急切并为每个查询支付实体的开销(可能这不好并且可能影响性能,但是是一个解决方案).
>将字段保持为惰性并在关闭Hibernate会话之前使用正确的get方法,以便代理在会话关闭后检索要使用的相关数据.

点赞