2016-08-20 55 views
0

我叫刀从我的服务为LazyInitializationException中在休眠:无法初始化代理 - 没有会话

@Override 
@Transactional 
public Product getProductById(int id) { 
    return productDao.getProductById(id); 
} 

而在DAO我收到的产品为

@Override 
public Product getProductById(int id) { 
    Product p = sessionFactory.getCurrentSession().load(Product.class, id); 
    System.out.print(p); 
    return p; 
} 

这将运行正常,但如果我更改我的dao类到

@Override 
public Product getProductById(int id) { 
    return sessionFactory.getCurrentSession().load(Product.class, id); 
} 

我得到org.hibernate.LazyInitializationException:无法初始化代理y - 没有会话。在我刚刚打印产品的视图层中发生异常。我不明白为什么在dao方法的同一行中返回导致视图图层中的异常,但如果将其保存在引用中然后返回它,则工作正常。

回答

1

以下是一个很好的reference,可让您熟悉.get()和.load()方法的工作原理。

@Override 
public Product getProductById(int id) { 
    Product p = sessionFactory.getCurrentSession().load(Product.class, id); 
    return p; 
} 

session.load()默认情况下会返回一个代理对象而不会触及数据库。如果表中没有任何记录,它基本上会返回NoObjectFoundError,否则它将返回一个引用而不填充实际对象,甚至不会触及数据库。 您的上述方法返回代理,并且由于它也必须初始化您的对象,所以会话保持打开并且对象被填充。

@Override 
public Product getProductById(int id) { 
    return sessionFactory.getCurrentSession().load(Product.class, id); 
} 

但在你的第二种方法中,基本上是一个代理没有任何初始化返回。会议之后没有任何使用前关闭。因此你得到错误。

希望帮助

0

当你处理Hibernate和视图层时,这是一个典型的问题。发生错误是因为在呈现视图之前Hibernate会话已关闭。解决这个问题的两个最简单的方法是使用Open Session In View模式,或者在视图呈现之前获取视图中需要的所有数据。

由于您使用的春天,第一个解决方案是最简单的一个 - 只要申请OpenSessionInViewFilter(或OpenEntityManagerInViewFilter如果你正在使用JPA):

http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/orm/hibernate4/support/OpenSessionInViewFilter.html http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/orm/jpa/support/OpenEntityManagerInViewFilter.html

你也应该读哪些利弊和使用OSIV模式的缺点。

0

此错误意味着您试图访问一个懒洋洋地加载的属性或集合,但Hibernate的Session被关闭或不可用。 在Hibernate中延迟加载意味着对象不会被填充(通过数据库查询),直到在代码中访问属性/集合。 Hibernate通过创建一个动态代理对象来实现这一点,只有当您第一次使用该对象时才会触及数据库。为了这个工作,你的对象必须在整个生命周期中连接到一个开放的Hibernate会话。

如果您删除SOP语句,那么对象根本不被访问,因此不会被加载。当你尝试在代码的其他部分代码中访问它时,它会抛出LazyInitializationException。

相关问题