2015-03-31 41 views
4

我使用JPA 2.1和Hibernate 4.3.7JPA Hibernate延迟多到一个获取代理

我试图调节我的应用程序,所以我把懒关系,只获取什么,我需要他们

当我重新加载实体时转为懒惰时,我遇到了多对一关系的问题即使我获取实体并且此代理未在视图部分(JSF)中工作,Hibernate也会用代理替换实体的应用程序。 问题disapear时多到一个是渴望模式,但冬眠执行一个选择更多每个许多到一个即使我不需要他们

@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 

=>一个选择查询=>速度快,但部门型机关_ $$ _ jvst3ac_5f的,这确实代理(employee.getDepartment()的getClass()另一方面,getCanonicalName()。)

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

=> 2个选择=>慢,但部门加载为系和一切:在应用程序

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查询的视图部分不能正常工作在应用程序的视图部分中处于良好状态

该关系是单向的,部门没有参照雇员

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


后Luiggi的回应,我将一种高精度的数据获取与懒惰多到一个+ fetch连接。当我做一个employee.getDepartment()。toString()时我有Department {id = 11,...}但这个部门的类仍然是Department _ $$ _ jvst3ac_5f。原因我不知道,即使数据被提取,JSF/PrimeFaces selectOneMenu组件也不能正常工作HibernateProxy

我尝试使用Hibernate批注@LazyToOne(LazyToOneOption.FALSE),另外还有@ManyToOne (fetch = FetchType.LAZY),但结果类似于@ManyToOne(fetch = FetchType.EAGER)单独...

+0

嗨,我知道这是相当一段时间,你有这个问题,但你找到了这个问题的优雅解决方案? – Tarator 2016-08-09 19:58:32

回答

2

问题是,当您使用延迟加载时,您将获得类的代理已经声明),并且该代理只有在休眠会话仍然打开的情况下才能从数据库获取数据。好像您的会话在将数据返回到视图时正在关闭,所以当试图在视图中使用延迟加载的字段时,您会收到异常。

可能的解决方案:

  • 保留字段提取渴望和付出的开销对你的实体每个查询(大概这是不好的,可能会影响性能,但它是一个解决方案)。
  • 在Hibernate会话关闭之前,将您的字段保持为懒惰并使用正确的get方法,以便代理检索会话关闭后要使用的相关数据。
+0

是的,保持领域的渴望似乎是不幸的唯一的解决方案,以避免多选择我添加一个左加入FETCH部门在evry查询,即使不需要部门(因为我在我的职位使用get精简不是一个解决方案) – kwisatz 2015-04-01 09:10:45

+0

@ kwisatz这是一个解决方案,你不能使用这种方法的事实是一个不同的故事。 – 2015-04-01 13:13:39

+0

这不是hibernate中的错误吗?如果我在自己的事务中执行一个查询,并且它有一些懒惰的字段没有被初始化,然后在一个新的事务中,我做了一个不同的查询,在这种情况下,先前懒惰的字段的同一个实体加载现在从数据库中急切地获取,不应该那个领域更新与新的热切取得的实体? – chrismarx 2015-09-03 13:36:20