我有非常简单的实体对象User,它与用户角色有关。令我不安的是,当我从DB获取User对象并将其传递给另一个想要访问该用户对象中的用户角色的方法时,我得到了着名的无法初始化代理Hibernate异常。
实施例。方法1:
- open session, open transaction
- fetch user
- close transaction, close session
现在将该用户对象传递给方法2
- open session, open transaction
- do Hibernate.initialize(user.getUserRole()) --> here it breaks
- close transaction, close session
我猜这是一些Hibernate功能,你不能在新会话中初始化对象,但我不知道为什么。这有什么解决方案吗?
PS。我已经阅读过关于<property name="hibernate.enable_lazy_load_no_trans">true</property>
的内容,但这种接缝与正常的事情一样,并且没有必要启用此选项。
编辑:代码示例:
用户类的getter和setter
@ManyToOne(fetch = FetchType.LAZY, targetEntity = UserRoles.class)
@JoinColumn(name = "USER_ROLE_ID", nullable = false)
public UserRoles getUserRoles() {
return this.userRoles;
}
public void setUserRoles(UserRoles userRoles) {
this.userRoles = userRoles;
}
UserRoles的字段
private Integer id;
private String description;
private Character active;
private Set userses = new HashSet(0);
方法1
public static void method1() {
Users user = null;
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
String hqlQuery = "FROM Users WHERE userName = :userName";
Query query = session.createQuery(hqlQuery);
query.setParameter("userName", userName);
List<Users> list = query.list();
for (Users u : list) {
user = u;
break;
}
tx.commit();
} catch (HibernateException e) {
if (tx != null)
tx.rollback();
Logging.handleExceptionLogging(e);
} finally {
session.close();
}
method2(user);
}
方法2
public static method2(Users user) {
if (user != null) {
if (Hibernate.isInitialized(user.getUserRoles())) {
if (user.getUserRoles().getDescription() != null && user.getUserRoles().getDescription().toLowerCase().equals("admin"))
returnValue = true;
} else {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
Hibernate.initialize(user.getUserRoles()); // this line causes Exception
if (user.getUserRoles().getDescription().toLowerCase().equals("admin"))
returnValue = true;
tx.commit();
} catch (HibernateException e) {
if (tx != null)
tx.rollback();
Logging.handleExceptionLogging(e);
} finally {
session.close();
}
}
}
}
答案 0 :(得分:4)
所以基本上经过大量的谷歌搜索和阅读会议后,我的假设是正确的。实体对象几乎是&#34;绑定&#34;到原始会话,他们被提取,这样的查询不能以这种方式执行。一种解决方案是将实体绑定到新会话调用session.update(entity),而不是这个新会话知道实体。基本上,新的查询将再次填充实体字段。因此,如果没有必要,请避免这种情况,并尝试在原始会话中获取所有需要的数据。