休眠无法初始化代理 - 无会话

我的代码检索与用户相关的所有信息:

SessionFactory sessionFactory = HibernateUtilities.configureSessionFactory();
Session session = sessionFactory.openSession();
UserDetails ud = null;
Set<Address> userAddress = null;

try {
    session.beginTransaction();
    ud = (UserDetails) session.get(UserDetails.class, 1);
    userAddress = ud.getAddresses();
    session.getTransaction().commit();
} catch (HibernateException e) {
    e.printStackTrace();
    session.getTransaction().rollback();
} finally {
    session.close();
}

System.out.println(ud.getName());

for(Address addr: userAddress){
    System.out.println("State " + addr.getState());
}

简单地返回用户的一组 es。ud.getAddresses()Address

我的问题是:为什么即使会话已经关闭,对象仍然有其值(例如,名称)? 是类的实例变量。但是为什么我不能检索它的值,但我可以检索该类的常规实例变量?udgetAddresses()UserDetailsUserDetails

ud.getAddresses()是一个 .@EmbeddedCollection


答案 1

我在JPA / Hibernate中遇到了同样的问题,有两种方法可以解决这个问题:

1/ 默认关闭 LAZY,如下所示:

@Entity
@Proxy(lazy = false)
public class Project {
...
}  

当然,由于性能问题,不建议使用这种方式,因此您可以转到第二种方式。

2/你可以把@Transactional放在你的方法的开头,它可以帮助你保持会话,或者另一种理解,它将会话的职责传递给休眠,如下所示:

@Test
@Transactional
public void testSaveGroup() {
    Department g = new Department();
    g.setName("XDG");
    assertNull(g.getId());
    this.groupRepo.save(g);
    assertNotNull(g.getId());
    System.out.println(g.getId());
    Project dummyPrj = new Project(123L, "KSTA", new Date(), "NEW", "Helm AG", g);
    this.projectRepo.save(dummyPrj);
    // verify
    List<Department> lst = this.groupRepo.findAll();
    Project savedPrj = this.projectRepo.getOne(123L);
    Assert.assertEquals("XDG", savedPrj.getGroup().getName());
}

我的回答很晚了,但希望能帮助别人:)


答案 2
userAddress = ud.getAddresses();
session.getTransaction().commit();
for(Address addr: userAddress) {

用于处理惰性关联的休眠文档清楚地指出这种访问是错误的。只有在会话仍处于打开状态时,才能与懒惰关联的对象进行交互。文档的这一部分还提供了访问对象的这种懒惰关联成员的替代方法,我们更愿意在应用程序中使用的条件中将获取模式指定为JOIN。