0

为什么在带有注释的方法返回后,我无法获取product.getName()id 加载的实体对象的值?当我以这种方式获得产品对象时,一切都很好。session.load(product.class,1)@Transactionalsession.createQuery("from Product as product WHERE product.id = 1)

编辑

道法

public Product getProduct(Long id) {
return (Product) currentSession().load(Product.class, id);
}

服务方式

    @Transactional
public Product getProduct(Long id) {
    return productDao.getProduct(id);
}

控制器方法 - 它应该发送 JSON,但它会因product.getName()错误而中断org.hibernate.LazyInitializationException: could not initialize proxy - no Session

    @RequestMapping(value = "/product",headers="Accept=application/json")
public @ResponseBody Product getProduct() {
    Product product = productService.getProduct(new Long(1));
    System.out.println(product.getName());
    return product;
}
4

2 回答 2

0

LazyInitializationException如果在 Session 范围之外访问未初始化的集合或代理,即当拥有集合或具有对代理的引用的实体处于分离状态时,Hibernate 将抛出A。

有时需要在关闭 Session 之前初始化代理或集合。您可以通过调用product.getName()或例如强制初始化。但是,这可能会使代码的读者感到困惑,并且对于通用代码来说也不方便。

静态方法Hibernate.initialize()和为应用程序提供了一种使用延迟初始化的集合或代理的Hibernate.isInitialized()便捷方式。Hibernate.initialize(product)将强制初始化代理,product只要其 Session 仍然打开。

你也可以声明你的一些字段是eagely加载的

@Entity 
public class Product  {

   @Id 
   @GeneratedValue
   private long id;


   @Basic(fetch=EAGER)
   private String name;


} 
于 2012-04-23T20:35:42.623 回答
-1

当我们在我们的 中创建实例时Java code, the instance is considered to be a transient instance,这意味着没有适当的机制来管理该实例的持久状态。然而,一旦we pass a transient instance to the save, update, or saveOrUpdate method of the Hibernate Session,我们认为瞬态实例已转换为持久实例,因为 Hibernate 将开始管理该实例的持久状态。

任何与 Hibernate Session 关联的实例都被称为持久实例。

保存或更新 JavaBean 并不是获得持久实例的唯一方法。通过 get 或 load 方法调用,甚至是 HQL 或条件查询,已加载到 Hibernate Session 中的 JavaBean 被认为是持久实例,因此,对这些实例状态的任何更改或更新都将是也由 Hibernate Session 持久化到数据库中。

如果你确实有一个你想从 Hibernate 的控制中释放的实例,你总是可以调用 Hibernate Session 的 evict 方法,传入你想从 Hibernate 的控制中释放的实例的名称。当一个实例不再由 Hibernate Session 管理其状态时,我们称其为分离实例,因为虽然它在数据库中确实有一个表示,但 Hibernate 并没有做任何事情来使实例与底层持久性存储保持同步. 实际上,该实例与其在数据库中的相应表示分离。

当然,当我们使用 Hibernate 时,我们与数据库的所有交互都必须发生在事务范围内。默认情况下,当我们调用 save 或 update 之类的方法时,我们永远无法完全确定数据库中的相应记录何时更新 - 我们可以肯定的是,一旦提交事务,所有对任何持久性的更改与 Hibernate Session 关联的实例将保存到数据库中。当然,将所有数据保存到数据库的行为总是有可能由于某种原因而失败,如果确实发生了这种情况,Hibernate 将抛出运行时异常。

在这一点上,除了回滚当前事务并关闭 Hibernate Session 之外,您真的没有太多可以做的。此时,之前在 Hibernate Session 控制下的所有实例都成为分离的对象,并且很可能不再与数据库同步。在这种情况下,您总是可以启动一个新事务,并尝试通过保存或更新调用将分离的实例与 Hibernate Session 重新关联,从而将它们转回持久实例,但最后,您可能会更好只需向您的客户端应用程序发送一条友好的错误消息,然后从头开始重新开始任何请求-响应循环。当我们谈论瞬态,持久和分离的对象时,我们的意思的简单描述。

于 2012-04-23T20:18:00.227 回答