10

我的代码检索与用户相关的所有信息:休眠无法初始化代理 - 没有会话

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()); 
} 

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

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

ud.getAddresses()@EmbeddedCollection

+0

“@EmbeddedCollection” - 你的意思是'@ ElementCollection'? –

回答

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

working with lazy associations的hibernate文档清楚地将这种访问称为错误。只有在会话仍处于打开状态时,才能与懒惰相关的对象进行交互。该文档的这一部分还提供了替代方法来访问此类懒惰关联的对象成员,并且我们更愿意在我们的应用程序中将获取模式指定为JOIN。

+0

因此,从它的外观来看,当我调用ud.getAddresses()时,它实际上是查询数据库? – KyelJmD

3

这些类的所有原始属性都会立即加载,除非您使用字节码增强功能,否则它们不会变得懒惰。只有像你的收藏这样的真实的联想可以是懒惰的。

+0

另一个类怎么样?是否被认为是一个懒惰的初始化? – KyelJmD

+0

*是*,如果涉及到MTO。并且*如果涉及到OTO,也许*。 –

+0

MTO和OTO是什么意思? – KyelJmD

11

我面临着同样的问题,在JPA /休眠,并有2种方式来解决这个问题:

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()); 
} 

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

+0

谢谢,@Transactional为我工作 –

相关问题